A snippet from my main method:
std::atomic_bool runflag;
// ...
std::thread signaller([&]() mutable {
while (runflag) {
int sig;
int rcode = sigwait(&set, &sig);
if (rcode == 0) {
switch (sig) {
case SIGINT: {
// handle ^C
}
}
}
}
});
while (runflag) {
next = cin.get();
// handle character input
}
signaller.join();
I'm using the sigwait()
-based approach for detecting SIGINT
sent from the command line.
The signaller
thread uses sigwait()
to listen for signals. The program terminates when runflag
is set false. However, the signaller
thread will still be blocked at sigwait
when this happens. I don't think I can use condition variables, as sigwait has no way to hook into one. Is there an alternative solution that is preferably not Linux-only?
EDIT 1: Alternatively, is there an interruptible version of sigwait?
CodePudding user response:
You can use the sigtimedwait()
function, which returns after a timeout given as a parameter.
You will need to check the return value from sigtimedwait()
to check if it finished because of timeout or the signal arrived and then depending on this value you will need to handle signal or just check runflag
and run again sigtimedwait()
.
Here is more about it from another answer: https://stackoverflow.com/a/58834251/11424134
CodePudding user response:
You can wake up the signal-handling thread by having the process send another signal to itself, eg.
kill(getpid(), SIGUSR1);