Обработка сигналов 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.