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.