With difficulties. Already the code you wrote has undefined behavior; You are not allowed to output the stream to a signal handler; In this case, you are not allowed to call exit
. (I base my claims here on the Posix standard. In pure C ++, all you are allowed to do is assign a variable of type sig_atomic_t
.)
In a simple case, such as your code, you can do something like:
sig_atomic_t stopFlag = 0; void handler( int ) { stopFlag = 1; } int main() { signal( SIGINT, &handler ); A a; while ( stopFlag == 0 ) { } std::cout << "will exit..." << std::endl; return 0; }
Depending on the application, you can do something like this by checking stopFlag
in the appropriate places. But in general, if you try this, there will be race conditions: you check stopFlag
before starting an intersystem system call, then a call; the signal arrives between the check and the call, you make the call, and this does not interrupt. (I used this technique, but in an application where the only intermittent system call was a socket read with a very short timeout.)
As a rule, at least in Posix you will have to create a signal processing thread; this can then be used to cleanly close all other threads. Basically, you start by setting the signal mask for all signals, then in the signal processing stream, after starting, set it to accept the signals of interest to you and call sigwait()
. This implies, however, that you follow all the usual steps necessary for a clean shutdown of threads: the signal processing thread must know about all other threads, call pthread_cancel
on them, etc., and you must generate the correct code for the pthread_cancel
to handle, or you need to develop some other ways to ensure that all threads are properly notified. (One would hope that today all compilers handle pthread_cancel
correctly. But no one knows; this is a significant execution cost and is usually not required.)
source share