Próbuję poprawnie zakończyć moją wielowątkową aplikację C++ 11 po otrzymaniu sygnału SIGINT (^C
), ale z jakiegoś powodu nie propaguje ona do wątków potomnych , chociaż główny wątek reaguje na to dobrze.Propagowanie sygnału (SIGINT) do C++ 11 wątków
Dla instnce (jak w przykładzie kodu poniżej), jeśli mamy jakąś funkcję blokowania wewnątrz wątku (jak sleep()
), to zajmie się całą ^C
kontrolę od Ciebie, jeśli zainstalowano żadnych haczyków SIGNT użyciu, powiedzmy, sigaction()
funkcji .
Czy istnieje sposób naprawienia lub obejścia takiego zachowania? Czy istnieje sposób propagowania odbieranych sygnałów do wątków potomnych?
EDIT: zastąpiony POSIX sleep()
z 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 więc rozwiązaniem było zastąpienie wszystkich blokowania połączeń z non-blocking odpowiedniki takich mechanizmów jak i zmiennych stanie i odpytywania .
Rzeczywiste pytanie pozostaje bez odpowiedzi, ponieważ aktualne oprogramowanie (i ewentualnie sprzęt) nie jest zaprojektowane w taki sposób, aby obsługiwać sygnały więcej niż w jednym wątku, który powinien informować innych, co mają robić po otrzymaniu sygnałów.
Czemu mieszanie funkcji POSIX 'sleep' z wątkami C++ 11? –
Tylko dla przykładu, w prawdziwej aplikacji jest to funkcja ZeroMQ send() z dokładnie takim samym efektem. –
cóż, w rzeczy samej, jest to zły przykład, powinienem zamiast tego użyć 'std :: this_thread :: sleep_for()'. Przepraszam, pozwól mi poprawić mój przykład. –