SIGINTシグナルを受信したときにマルチスレッドC++11アプリケーションを正しく終了しようとしていますが(^C
そうです)、メインスレッドはそれに応答しますが、何らかの理由で子スレッドに伝播しません。
たとえば、(以下のコードサンプルのように)スレッド内にブロッキング関数がある場合、たとえば関数を使用してSIGNTフックをインストールすると、sleep()
すべての制御が失われます。^C
sigaction()
そのような動作を修正または回避する方法はありますか?主に受信した信号を子スレッドに伝播する方法はありますか?
編集:POSIXsleep()
を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 したがって、解決策は、すべてのブロッキング呼び出しを非ブロッキングの対応物と、条件変数やポーリングなどのメカニズムに置き換えることでした。
現在のソフトウェア(および場合によってはハードウェア)は、信号を受信したときに他の人に何をすべきかを指示することになっている1つのスレッドで信号を処理するように設計されていないため、実際の質問には答えられません。