Obsługa sygnałów w C ++
Sygnały to przerwania dostarczane do procesu przez system operacyjny, które mogą zakończyć program przedwcześnie. Możesz generować przerwania, naciskając Ctrl + C w systemie UNIX, LINUX, Mac OS X lub Windows.
Istnieją sygnały, których program nie może wychwycić, ale jest następująca lista sygnałów, które można przechwycić w programie i na ich podstawie podjąć odpowiednie działania. Sygnały te są zdefiniowane w pliku nagłówkowym C ++ <csignal>.
Sr.No | Sygnał i opis |
---|---|
1 | SIGABRT Nieprawidłowe zakończenie programu, na przykład wywołanie abort. |
2 | SIGFPE Błędna operacja arytmetyczna, taka jak dzielenie przez zero lub operacja powodująca przepełnienie. |
3 | SIGILL Wykrycie niedozwolonej instrukcji. |
4 | SIGINT Otrzymanie interaktywnego sygnału uwagi. |
5 | SIGSEGV Nieprawidłowy dostęp do pamięci. |
6 | SIGTERM Żądanie zakończenia wysłane do programu. |
Funkcja signal ()
Biblioteka obsługi sygnałów C ++ zapewnia funkcje signaldo łapania nieoczekiwanych wydarzeń. Poniżej znajduje się składnia funkcji signal () -
void (*signal (int sig, void (*func)(int)))(int);
Upraszczając, funkcja ta otrzymuje dwa argumenty: pierwszy argument jako liczbę całkowitą, która reprezentuje numer sygnału, a drugi argument jako wskaźnik do funkcji obsługi sygnału.
Napiszmy prosty program w C ++, w którym złapiemy sygnał SIGINT za pomocą funkcji signal (). Jakikolwiek sygnał chcesz przechwycić w swoim programie, musisz zarejestrować ten sygnał za pomocąsignalfunkcji i skojarz ją z obsługą sygnału. Przeanalizuj następujący przykład -
#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;
}
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
Going to sleep....
Going to sleep....
Going to sleep....
Teraz naciśnij Ctrl + c, aby przerwać program, a zobaczysz, że twój program złapie sygnał i wyjdzie, drukując coś w następujący sposób -
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.
Funkcja raise ()
Możesz generować sygnały według funkcji raise(), który przyjmuje jako argument liczbę całkowitą sygnału i ma następującą składnię.
int raise (signal sig);
Tutaj, sigto numer sygnału do wysłania dowolnego z sygnałów: SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGHUP. Poniżej znajduje się przykład, w którym wewnętrznie podnosimy sygnał za pomocą funkcji raise () w następujący sposób -
#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;
}
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik i pojawia się automatycznie -
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.