Обработка сигналов в Linux на C++

Большинство программ не обрабатывает сигналы в явном виде, это скорее потому, что высокоуровневые библиотеки сами заботятся об этом. И программисту можно не беспокоится.
Но часто нужно написать консольную утилиту, или демон, которые просто обязаны уметь совладать с обработкой сообщений.

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

Будем обрабатывать сигнал завершения программы. Ведь нужно иногда перед завершением сохранить информацию и т.д.
Мы же просто выведем сообщение о завершении.
Обработчик:

void term_handler(int i){
    printf ("Terminating\n");
    exit(EXIT_SUCCESS);
}

Вообще весь механизм очень похож на работу с прерываниями в микроконтроллерах. Обработчик сигнала (как и прерывание) будет выполнен при поступлении сигнала независимо от действий выполняемых программой.
Теперь main функция:

int main(int argc, char ** argv) {
    struct sigaction sa;
    sigset_t newset;
    sigemptyset(&newset);   // чистимся
    sigaddset(&newset, SIGHUP);  // добавляем сигнал SIGHUP
    sigprocmask(SIG_BLOCK, &newset, 0);   // блокируем его
    sa.sa_handler = term_handler;  // указываем обработчик
    sigaction(SIGTERM, &sa, 0);    // обрабатываем сигнал SIGTERM
    printf("My pid is %i\n", getpid());  // выводим PID процесса
    printf("Waiting...\n");  
    while(1) sleep(1);  // ждём
    return EXIT_FAILURE;
}

В ходе программы мы создаём экземпляр структуры sigaction для назначения обработчика. Мы блокируем сигнал SIGHUP для того, чтобы он не завершил программу раньше чем нам нужно и обрабатываем SIGTERM. После всех настроек мы просто ожидаем.
Вывод программы:

My pid is 4019
Waiting...

Если завершить программу будет выведено сообщение:

Terminating

Удачи в ваших начинаниях.

Просмотров:   6268