Нет, по умолчанию большинство сигналов вызывают немедленный ненормальный выход из вашей программы.
Однако вы можете легко изменить поведение по умолчанию для большинства сигналов.
Этот код показывает, как заставить сигнал нормально выходить из вашей программы, включая вызов всех обычных деструкторов:
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <cstring>
#include <atomic>
std::atomic<bool> 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;
}
Если вы запустите эту программу и нажмете control-C, вы должны увидеть слово «деструктор». Помните, что ваши функции-обработчики сигналов (got_signal) редко должны выполнять какую-либо работу, кроме установки флага и тихого возврата, если вы действительно не знаете, что делаете.
Большинство сигналов являются перехватываемыми, как показано выше, но не SIGKILL, вы не можете его контролировать, потому что SIGKILL - это последний метод для уничтожения сбегающего процесса, а не SIGSTOP, который позволяет пользователю заморозить процесс. Обратите внимание, что вы можете перехватить SIGTSTP (control-Z) при желании, но вам не нужно, если ваш единственный интерес к сигналам - это поведение деструктора, потому что в конечном итоге после control-Z процесс будет активирован, он продолжит работу и выйдет нормально со всеми действующими деструкторами.