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

Сигналы - это прерывания, доставляемые процессу операционной системой, которые могут преждевременно завершить программу. Вы можете сгенерировать прерывания, нажав Ctrl + C в системе UNIX, LINUX, Mac OS X или Windows.

Есть сигналы, которые программа не может уловить, но есть следующий список сигналов, которые вы можете уловить в своей программе и предпринять соответствующие действия на основе сигнала. Эти сигналы определены в заголовочном файле C ++ <csignal>.

Старший Нет Сигнал и описание
1

SIGABRT

Аномальное завершение программы, например, вызов abort.

2

SIGFPE

Ошибочная арифметическая операция, например деление на ноль или операция, приводящая к переполнению.

3

SIGILL

Обнаружение незаконной инструкции.

4

SIGINT

Получение интерактивного сигнала внимания.

5

SIGSEGV

Недействительный доступ к хранилищу.

6

SIGTERM

Запрос на завершение, отправленный программе.

Функция signal ()

Библиотека обработки сигналов C ++ предоставляет функцию signalловить неожиданные события. Ниже приведен синтаксис функции signal () -

void (*signal (int sig, void (*func)(int)))(int);

Для простоты эта функция получает два аргумента: первый аргумент как целое число, представляющий номер сигнала, и второй аргумент как указатель на функцию обработки сигнала.

Давайте напишем простую программу на C ++, в которой мы будем ловить сигнал SIGINT с помощью функции signal (). Какой бы сигнал вы ни хотели уловить в своей программе, вы должны зарегистрировать этот сигнал, используяsignalфункцию и свяжите ее с обработчиком сигнала. Рассмотрим следующий пример -

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum ) {
   cout << "Interrupt signal (" << signum << ") received.\n";

   // cleanup and close up stuff here  
   // terminate program  

   exit(signum);  
}

int main () {
   // register signal SIGINT and signal handler  
   signal(SIGINT, signalHandler);  

   while(1) {
      cout << "Going to sleep...." << endl;
      sleep(1);
   }

   return 0;
}

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

Going to sleep....
Going to sleep....
Going to sleep....

Теперь нажмите Ctrl + c, чтобы прервать программу, и вы увидите, что ваша программа поймает сигнал и выйдет, напечатав что-то следующее:

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

Функция raise ()

Вы можете генерировать сигналы по функциям raise(), который принимает в качестве аргумента целочисленный номер сигнала и имеет следующий синтаксис.

int raise (signal sig);

Вот, sig- это номер сигнала для отправки любого из сигналов: SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGHUP. Ниже приведен пример, в котором мы поднимаем сигнал внутренне с помощью функции raise () следующим образом:

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum ) {
   cout << "Interrupt signal (" << signum << ") received.\n";

   // cleanup and close up stuff here  
   // terminate program  

   exit(signum);  
}

int main () {
   int i = 0;
   // register signal SIGINT and signal handler  
   signal(SIGINT, signalHandler);  

   while(++i) {
      cout << "Going to sleep...." << endl;
      if( i == 3 ) {
         raise( SIGINT);
      }
      sleep(1);
   }

   return 0;
}

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

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.