Я установил обработчик сигнала, как показано ниже на c ++, для приложения, предназначенного для работы на linux:
Установите обработчик сигнала для вызова функции stati c:
// Setup the SIGNTERM signal handler for kill/pkill or systemd terminate
if (signal(SIGTERM, manager_signal_handler) == SIG_ERR)
{
ERROR << "Failed to add signal SIGTERM to signal handler with error code: " << std::strerror(errno) << ENDL;
}
Обработчик сигнала stati c - который вызывает функцию-член экземпляра класса
static dds_manager_base *p_this_dds_manager_base = nullptr;
static void dds_manager_signal_handler(int signum)
{
if (p_this_manager_base)
{
DEBUG << "static manager_signal_handler calling: p_this_manager_base->signal_handler\n";
p_this_manager_base->signal_handler(signum);
}
else
{
ERROR << "manager_signal_handler - manager pointer not set\n";
}
}
Функция-член - обрабатывает сигнал:
void dds_manager_base::signal_handler(int signum)
{
DEBUG << "dds_manager_base::signal_handler - received signal: " << signum << ENDL;
// Termination actions - can take 5-10 seconds...
}
Я использую sytemctnl powerdown
до отключения linux (что останавливает службу, в которой запущено мое приложение). Я заметил, что мое приложение получает 2 или даже 3 сигнала SIGTERM с интервалом около 500 мс.
Я могу справиться с этой ситуацией, но я ожидал, что 1 SIGTERM, за которым следует SIGABRT, может быть, через 90 секунд, если мое приложение не завершается в течение этого срока.
Моя проблема в том, что, как только я обрабатываю сигнал, в некоторых случаях мое приложение завершается достаточно быстро, чтобы мой класс больше не существовал, и я получаю дамп ядра, потому что signal_handler () функции больше нет Таким образом, у меня была идея вернуть сигнал на default behaviour signal(SIGTERM, SIG_DFL);
, как только я обработал сигнал - но поскольку systemd вызывает SIGTERM более одного раза при втором вызове, std::exit()
(я полагаю, что это поведение по умолчанию) вызывается и завершается мое приложение, прежде чем оно сможет корректно завершить работу.
Вот мой файл службы / модуля:
[Unit]
Description=Invoke script to start the corvus application
After = network.target mnt-appdata.mount
[Service]
Type=idle
ExecStart=/mnt/appdata/deploy/services/start_module.sh ${SYS_NUM} ${DDS_NUM}
[Install]
WantedBy=multi-user.target
Вы можете видеть, что скрипт start_module.sh
является вызовом - это то, что затем запускает мое приложение выполнив: ./my-application &
Итак, мои вопросы: - Почему я получаю более одного SIGTERM и так близко друг к другу? - Что я могу сделать, чтобы решить эту проблему?