Обработка сигналов для обеспечения вызова деструкторов в C ++ - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть класс с конструктором и деструктором.Давайте назовем этот класс учеником.

Предположим, есть какой-то код

{
    //some code
    Student student;
    //signal , may be ctrl+c or any other signal

}

Что я хочу, так это, когда выдается сигнал, я все же хочу, чтобы деструктор объекта ученика вызывался.

У меня есть некоторые базовые знания о сигналах, но я не знаю, как это сделать.

Я знаю, что это может быть характерно для o / s;Я пытаюсь для Linux.

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Вы МОЖЕТЕ в соответствии со стандартом также позвонить std::quick_exit.Вам нужно зарегистрировать некоторую функцию очистки с помощью std::at_quick_exit.Как пример:

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <set>
#include <signal.h>
#include <unistd.h>

using namespace std;

class K
{
public:
    K(const char* _name)
    : name(_name)
    { cout << "K() for " << name << endl; registered.emplace(this); }
    ~K()
    { cout << "~K() for " << name << endl; registered.erase(this); }

    static void cleanup()
    {
        for (auto i: registered) {
            i->~K();
        }
    }

private:
    const char* name= nullptr;
    static set<K*> registered;
};
set<K*> K::registered;

extern "C"
void signalHandler(int sig, siginfo_t* info, void* context)
{
    if (sig == SIGKILL || sig == SIGTERM || sig == SIGINT) {
        quick_exit(1);
    }
    return;
}

K k1("global k1");

int main(int argc, const char* argv[])
{
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    act.sa_sigaction= signalHandler;
    act.sa_flags= SA_SIGINFO;
    sigemptyset(&act.sa_mask);
    for (int i= 0; i < 64; i++) {
        sigaction(i, &act, nullptr);
    }

    K k2("local k2");
    at_quick_exit(K::cleanup);
    for (int i= 0; i < 10; i++) {
        cout << "." << flush;
        sleep(1);
    }
    cout << "Normal exit" << endl;

    return 0;
}
0 голосов
/ 28 февраля 2019

Это не может быть легко сделано в C ++.

Вам необходимо обработать сигнал .Обработчик должен сообщить программе о событии.Программа должна отреагировать, аккуратно завершив работу (чаще всего это происходит путем генерирования исключения; естественно, ваша программа должна обеспечить безопасность исключений, чтобы это работало).

Проблема заключается в последовательности информирования и реагирования.Нет хорошего способа сделать это.Согласно стандарту, only , что разрешено делать обработчику сигналов, - это установить глобальную переменную типа sig_atomic_t и return.Следовательно, программа должна периодически проверять значение этой переменной и реагировать на изменение ее значения.

Некоторые операционные системы могут разрешать больше вещей, которые безопасно делать в обработчике исключений.Однако создание исключения C ++ обычно не является одной из таких вещей.Сигналы имеют асинхронный характер.Если он доставляется, когда объект находится в середине конструкции, создание исключения может привести к тому, что его состояние будет непоследовательным.

Так что единственный способ - вставить чеки в программу или, если она имеет централизованный ввод-вывод или цикл обработки событий, вставить туда чек.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...