Я запускаю приложение C ++ на xubuntu и реализовал обработчик сигнала, который обрабатывает SIGINT. Моя реализация должна быть в порядке, так как она работает на всех других машинах (той же ОС) — кроме моей. «Рабочий» означает, что сигнал принимается потоком обработчика сигнала и выполняется контролируемое отключение.
На моей машине ctrl + c просто убивает мое приложение. Никакой обработки, только «^ C» на консоли.
У кого-нибудь есть идея, почему это поведение зависит от машины? Могу ли я проверить какие-либо настройки? Благодарю.
РЕДАКТИРОВАТЬ:
чтобы увидеть, связано ли это с терминалом ctrl + c, я попробовал kill -2 PID вместо ctrl + c: то же поведение, без обработки на моей машине, обработка, как и ожидалось, на других машинах.
Вот пример кода моего обработчика сигнала:
std::atomic_bool shutdown_requested;
void SignalHandler() {
sigset_t signal_set;
sigemptyset(&signal_set);
sigaddset(&signal_set, SIGTERM);
sigaddset(&signal_set, SIGINT);
while (!shutdown_requested) {
int sig = SIGUNUSED;
sigwait(&signal_set, &sig);
switch (sig) {
case SIGINT:
case SIGTERM:
shutdown_requested = true;
break;
}
}
}
void SetSignalHandler() {
sigset_t signals;
sigfillset(&signals);
pthread_sigmask(SIG_SETMASK, &signals, nullptr);
std::thread(SignalHandler);
}
Atomic shutdown_requested сигнализирует об отключении основного потока. Есть идеи?
Я не буду обрабатывать сигналы, порождающие новый поток, но я бы просто использовал signal()
(см. «сигнал человека 2»).
Я думаю, что так как вы не устанавливаете новый обработчик сигнала с signal()
(несмотря на его название, ваш SignalHandler()
это не обработчик сигнала, это просто цикл выполнения потока), по умолчанию он остается активным. В некоторых системах ваш поток работает быстрее и корректно завершается, в других системах стандартный обработчик SIGINT выигрывает, и ваше приложение уничтожается.
Возможно, другим подходом было бы сделать отключение сигналов на процессе с sigprocmask()
, но это был бы довольно странный подход к обработке сигналов.
Однако я угадал. Ваш пример не работает — Если мое предположение неверно, я бы предложил подготовить MCVE как рекомендуется в руководящих принципах stackoverflow.
Других решений пока нет …