向c++ 11线程传播信号(SIGINT)
Propagating Signal (SIGINT) to C++11 threads
我试图在接收SIGINT信号(^C
)时正确终止我的多线程c++ 11应用程序,但由于某种原因它没有传播到子线程,虽然主线程对它的响应很好。
例如(如下面的代码示例),如果我们在线程内部有一些阻塞函数(如sleep()
),如果您使用sigaction()
函数安装任何SIGNT钩子,它将从您那里取出所有^C
控制。
是否有任何方法来修复或解决这种行为?是否有一种方法来传播主接收信号到子线程?
EDIT:用c++ 11 std::this_thread::sleep_for()
替换POSIX sleep()
#include <iostream>
#include <thread>
#include <chrono>
#include <signal.h> // for sigaction() function
static int signaled = 0;
void threaded_foo() {
while (!signaled) {
// pressing ^C now will not lead to correct termination, because we are
// sleeping for a long time (100500 seconds) and do not respond to
// SIGINT for some tricky reason i am looking a bypassage for.
std::chrono::seconds duration(100500);
std::this_thread::sleep_for(duration);
}
std::cout << "Correct terminationn";
}
void sighandler(int sig, siginfo_t *siginfo, void *context) {
signaled = 1;
}
void install_sig_hooks() {
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_sigaction = sighandler;
action.sa_flags = SA_SIGINFO;
sigaction(SIGINT, &action, NULL);
}
int main(int argc, char **argv) {
install_sig_hooks();
std::thread t(threaded_foo);
t.join();
return 0;
}
EDIT2 因此,解决方案是将所有阻塞调用替换为非阻塞调用,以及诸如条件变量和轮询之类的机制。
实际的问题仍然没有答案,因为当前的软件(可能还有硬件)没有设计成在一个线程中处理多个信号的方式,哪个线程应该告诉其他线程在接收信号时做什么。
我试图正确终止我的多线程c++ 11应用程序在接收SIGINT信号(^C它是),但由于某种原因,它不传播到子线程,虽然主线程响应它很好。
POSIX区分目标处理或线程的信号。无论哪种情况,只有一个线程接收到信号:
在多线程进程中,一个常见的解决方案是阻塞除一个线程外的所有线程中打算处理的进程信号。一个线程通常会处理所有进程信号,并告诉其他线程该做什么(例如终止)。在产生信号时,应确定该信号是为进程产生的,还是为进程内的特定线程产生的。由特定线程的某些动作产生的信号,例如硬件故障,应该为引起信号产生的线程产生信号。应为该进程生成与进程ID或进程组ID或异步事件(如终端活动)相关联的信号。
…
…为进程生成的信号应该准确地传递给进程中调用sigwait()函数选择该信号或未阻塞信号传递的线程之一。如果在调用sigwait()函数时没有线程选择该信号,并且如果进程中的所有线程都阻塞了信号的传递,则该信号将在进程中保持挂起状态,直到线程调用sigwait()函数选择该信号,线程解除对信号传递的阻塞,或者与该信号相关的操作被设置为忽略该信号。
另外,因为signaled
是由信号处理程序设置的,所以它应该声明为volatile
,这是引入volatile
的两个用例之一:
static int volatile signaled = 0;
- Qt VTK交互风格的信号到小部件
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何在没有信号的情况下从C++执行QML插槽
- 线程之间的布尔停止信号
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 当用户在qtablewidget中输入单元格时,如何获得信号?C++
- 有可能在信号处理程序中设置promise吗
- 代码在我的计算机上运行良好,但是在将其提交给coursera时遇到未知的信号11问题
- 在条件变量中触发错误信号的频率是多少
- 在信号处理程序中捕获C++未处理的异常并恢复应用程序
- 调试和自由执行中的信号处理
- 升压信号2将插槽传递到成员功能以断开连接
- C++函数包装器来捕获某些信号
- 如何防止在C++中使用 popen() 打开的进程接收 SIGINT 信号?
- sigaction SIGINT,程序在 & (background) 中运行,没有得到信号
- 使用 select() 时无法捕获 SIGINT 信号
- SIG_IGN忽略SIGINT信号失败
- 向c++ 11线程传播信号(SIGINT)
- 如何多次发送SIGINT信号