Il distruttore viene chiamato se SIGINT o SIGSTP sono stati emessi?

Ho una class con un distruttore definito dall’utente. Se la class è stata istanziata inizialmente, e quindi SIGINT viene emesso (usando CTRL + C in unix) mentre il programma è in esecuzione, verrà chiamato il distruttore? Qual è il comportamento di SIGSTP (CTRL + Z in unix)?

No, per impostazione predefinita, la maggior parte dei segnali causa un’uscita immediata e anormale del programma.

Tuttavia, è ansible modificare facilmente il comportamento predefinito per la maggior parte dei segnali.

Questo codice mostra come fare un segnale di uscire normalmente dal tuo programma, incluso chiamare tutti i soliti distruttori:

#include  #include  #include  #include  #include  std::atomic quit(false); // signal flag void got_signal(int) { quit.store(true); } class Foo { public: ~Foo() { std::cout << "destructor\n"; } }; int main(void) { struct sigaction sa; memset( &sa, 0, sizeof(sa) ); sa.sa_handler = got_signal; sigfillset(&sa.sa_mask); sigaction(SIGINT,&sa,NULL); Foo foo; // needs destruction before exit while (true) { // do real work here... sleep(1); if( quit.load() ) break; // exit normally after SIGINT } return 0; } 

Se esegui questo programma e premi control-C, dovresti vedere la parola "destructor" stampata. Siate consapevoli del fatto che le funzioni del vostro gestore di segnale (got_signal) dovrebbero raramente svolgere qualsiasi lavoro, tranne che impostare una bandiera e tornare tranquillamente, a meno che non si sappia davvero cosa si sta facendo.

La maggior parte dei segnali è catchable come mostrato sopra, ma non SIGKILL, non si ha il controllo su di esso perché SIGKILL è un metodo last-ditch per uccidere un processo in fuga, e non SIGSTOP che consente a un utente di congelare un processo a freddo. Nota che puoi catturare SIGTSTP (control-Z) se lo desideri, ma non è necessario se il tuo unico interesse per i segnali è il comportamento del distruttore, perché alla fine dopo un controllo-Z il processo verrà ritriggersto, continuerà a funzionare e uscirà normalmente con tutti i distruttori in vigore.

Se non gestisci questi segnali da solo, allora, no, i distruttori non vengono chiamati. Tuttavia, il sistema operativo recupererà tutte le risorse utilizzate dal programma al momento della sua conclusione.

Se desideri gestire autonomamente i segnali, sigaction considerazione di verificare la funzione di libreria standard sigaction .

Proviamolo:

 #include  #include  class Foo { public: Foo() {}; ~Foo() { printf("Yay!\n"); } } bar; int main(int argc, char **argv) { sleep(5); } 

E poi:

 $ g++ -o test ./test.cc $ ./test ^C $ ./test Yay! 

Quindi temo di no, dovrai prenderlo.

Per quanto riguarda SIGSTOP , non può essere catturato e mette in pausa il processo fino a quando SIGCONT viene inviato un SIGCONT .