我试图在接收到SIGINT信号(^C
)时正确终止我的多线程C++ 11应用程序,但由于某些原因,它不会传播到子线程,尽管主线程很好地回应了它。向C++ 11线程传播信号(SIGINT)
对于instnce(如下面的代码样本中),如果我们有螺纹(类似sleep()
)内部的一些阻塞函数,它会拿出从你所有^C
控制,如果你使用,比如安装在任何SIGNT挂钩,sigaction()
功能。
有什么方法可以解决或解决此类问题? 有没有办法将主要接收的信号传播给子线程?
EDIT:取代POSIX sleep()
与C++ 11 std::this_thread::sleep_for()
#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 termination\n";
}
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 所以该溶液来代替与非阻断-同行等机制,条件变量和轮询所有阻塞调用。
实际的问题仍然没有得到解答,因为目前的软件(也可能是硬件)并非设计成在一个线程中处理信号,而是在一个线程中处理信号,这个线程应该告诉别人接收信号时该做些什么。
你为什么混合POSIX'sleep'功能用C++ 11线程? – 2013-03-27 11:47:30
只是为了举例,在实际应用中它是ZeroMQ send()函数,具有完全相同的效果。 – 2013-03-27 11:48:08
好吧,的确,这是一个糟糕的例子,我肩负着使用'std :: this_thread :: sleep_for()'来代替。对不起,让我纠正我的例子。 – 2013-03-27 11:51:53