Подтвердить что ты не робот

Вызывается деструктор, если выдает SIGINT или SIGSTP?

У меня есть класс с определяемым пользователем деструктором. Если сначала был создан экземпляр класса, а затем выдается SIGINT (используя CTRL + C в unix) во время работы программы, будет ли вызван деструктор? Каково поведение SIGSTP (CTRL + Z в unix)?

4b9b3361

Ответ 1

Нет, по умолчанию большинство сигналов вызывают немедленный ненормальный выход вашей программы.

Однако вы можете легко изменить поведение по умолчанию для большинства сигналов.

Этот код показывает, как заставить сигнал нормально выходить из вашей программы, включая вызов всех обычных деструкторов:

#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;
}

Если вы запустите эту программу и нажмите Ctrl-C, вы увидите сообщение "destructor". Имейте в виду, что функции обработчика сигнала (got_signal) должны редко выполнять какую-либо работу, кроме установки флага и возвращения тихо, если вы действительно не знаете, что делаете.

Большинство сигналов улавливаются, как показано выше, но не SIGKILL, вы не контролируете его, потому что SIGKILL - это метод последней остановки для уничтожения процесса убегания, а не SIGSTOP, который позволяет пользователю заморозить процесс холода. Обратите внимание, что вы можете поймать SIGTSTP (control-Z), если это необходимо, но вам не нужно, если ваш единственный интерес к сигналам является деструкторным поведением, потому что, в конце концов, после управления Z процесс будет разбужен, будет продолжаться, и будет нормально работать со всеми деструкторами, действующими.

Ответ 2

Если вы сами не обрабатываете эти сигналы, то нет, деструкторы не вызываются. Тем не менее, операционная система будет восстанавливать любые ресурсы, используемые вашей программой при ее завершении.

Если вы хотите сами обрабатывать сигналы, попробуйте проверить стандартную библиотечную функцию sigaction.

Ответ 3

Попробуйте:

#include <stdio.h>
#include <unistd.h>

class Foo {
public:
  Foo() {};
  ~Foo() { printf("Yay!\n"); }
} bar;

int main(int argc, char **argv) {
  sleep(5);
}

И затем:

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

Так что, боюсь, нет, вам придется поймать его.

Что касается SIGSTOP, он не может быть пойман и приостанавливает процесс до отправки SIGCONT.