Possible Duplicate:
Is destructor called if SIGINT or SIGSTP issued?
My code like this:
#include <iostream>
#include <signal.h>
#include <cstdlib>
void handler(int) {
std::cout << "will exit..." << std::endl;
exit(0);
}
class A {
public:
A() {std::cout << "constructor" << std::endl;}
~A() {std::cout << "destructor" << std::endl;}
};
int main(void) {
signal(SIGINT, &handler);
A a;
for (;;);
return 0;
}
When I pressed Ctrl-C, it printed:
constructor
^Cwill exit...
There is no “destructor” printed.
So, how can I exit cleanly?
With difficulty. Already, the code you’ve written has undefined
behavior; you’re not allowed to output to a stream in a signal handler;
for that matter, you’re not allowed to call
exiteither. (I’m basingmy assertions here on the Posix standard. In pure C++, all you’re
allowed to do is assign to a variable of
sig_atomic_ttype.)In a simple case like your code, you could do something like:
Depending on the application, you may be able to do something like this,
checking the
stopFlagat appropriate places. But generally, if youtry this, there will be race conditions: you check
stopFlagbeforestarting an interuptable system call, then do the call; the signal
arrives between the check and the call, you do the call, and it isn’t
interrupted. (I’ve used this technique, but in an application where the
only interruptable system call was a socket read with a very short
timeout.)
Typically, at least under Posix, you’ll end up having to create a signal
handling thread; this can then be used to cleanly shut down all of the
other threads. Basically, you start by setting the signal mask to block
all signals, then in the signal handling thread, once started, set it to
accept the signals you’re interested in and call
sigwait(). Thisimplies, however, that you do all of the usual actions necessary for a
clean shutdown of the threads: the signal handling thread has to know
about all other threads, call
pthread_cancelon them, etc., and you’recompiler has to generate the correct code to handle
pthread_cancel, oryou need to develop some other means of ensuring that all threads are
correctly notified. (One would hope, today, that all compilers handle
pthread_cancelcorrectly. But one never knows; doing so hassignificant runtime cost, and is not usually needed.)