Sygnały

Z Linux Wiki
(Przekierowano z SIGTERM)
Skocz do: nawigacja, szukaj

Sygnały – jeden z podstawowych sposobów komunikacji międzyprocesowej w systemach uniksowych, w tym również w Linuksie.

Sygnałami są po prostu liczby określone całkowite. Jeśli jakiś proces otrzyma sygnał, jądro systemu zatrzyma na chwilę jego dotychczasowe działanie i sprawdzi, czy posiada on kod obsługujący dany sygnał. Jeśli tak - uruchomi go, w przeciwnym wypadku - kontynuuje normalne wykonywanie procesu.

Wysyłanie sygnałów[edytuj]

Z poziomu poleceń terminala[edytuj]

Do wysyłania sygnałów z poziomu konsoli służy polecenie kill. Jej użycie ma postać

$ kill [przełączniki] <PID> ...

Jeśli nie podane zostaną żadne przełączniki zostanie wysłany sygnał SIGTERM. Aby wysłać inny sygnał, wystarczy podać go poprzedzonego myślnikiem (-). Przykładowo, wysłanie sygnału SIGUSR1 o wartości 10 do procesu o numerze 1234, wygląda tak:

$ kill -10 1234

Z poziomu programu[edytuj]

Wysłanie sygnału z poziomu programu jest możliwe dzięki wywołaniu systemowemu kill(). Jako pierwszy parametr pobiera ono sygnał, który ma zostać wysłany (w przypadku języka C można posłużyć się makrami zdefiniowanymi w pliku nagłówkowym <signal.h>), a jako drugi - PID procesu, który ma otrzymać sygnał. Umożliwia wysłanie tylko jednego sygnału naraz. W przypadku powodzenia zwraca 0, w przeciwnym wypadku - -1. Użycie tego wywołania (w C) polegające na wysłaniu SIGUSR1 do procesu o numerze 1234, wygląda tak:

kill(10, 1234);

lub, by użyciu makr z nazwami (wymaga załączenia <signal.h>):

kill(SIGUSR1, 1234);

Obsługa sygnałów[edytuj]

Za obsługę sygnałów odpowiada wywołanie systemowe signal(). Jako pierwszy argument przyjmuje ona sygnał numer sygnału, a jako drugi - wskaźnik do funkcji, która ma odpowiadać za obsługę tego sygnału. W momencie wywołania do owej funkcji przekazany zostanie argument w postaci numeru sygnału (umożliwia to używanie wspólnej funkcji dla wielu sygnałów).

Przykładowy program[edytuj]

Poniższy program napisany w C po uruchomieniu czeka w nieskończoność, aż otrzyma sygnał SIGUSR1. Po jego otrzymaniu wyświetli odpowiednią informację i zakończy działanie.

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
 
void funkcja_obslugujaca_sigusr1(int numer) {
  puts("Mam SIGUSR1.");
  puts("Kończę pracę...");
  exit(0);
}
 
int main(void) {
  signal(SIGUSR1, funkcja_obslugujaca_sigusr1);
  while (1) {
    sleep(3600);
  }
  return 0;
}

Wyjście programu, po umieszczeniu tekstu w pliku program.c, wykonaniu trzech poleceń i wysłaniu po tym signału SIGUSR1 dowolnym sposobem:

$ gcc program.c -o program
$ chmod +x program
$ ./program
Mam SIGUSR1.
Kończę pracę...

Standardowe sygnały[edytuj]

SIGCHLD[edytuj]

Sygnał wysyłany przez jądro systemu do procesu, gdy jakiś jego proces-dziecko zakończy swe działanie. Jego numer to 18, a jego nazwa pochodzi od angielskiego słowa child. Domyślnie jest ignorowany przez proces, ale może to zostać zmienione.

SIGFPE[edytuj]

Sygnał wysyłany przez jądro do procesu, który próbował dokonać niemożliwej operacji arytmetycznej (np. dzielenia przez zero). Ma numer 8. FPE w jego nazwie oznacza floating-point exception i jest mylące, gdyż sygnał jest też używany w przypadku liczb całkowitych, nie tylko zmienno przecinkowych.

Domyślnie powoduje natychmiastowe zatrzymanie działania procesu, jednak zachowanie to można zmienić.

SIGKILL[edytuj]

Sygnał używany do zabijania procesów. Ma numer 9, a jego nazwa pochodzi od angielskiego słowa kill. Po jego otrzymaniu proces natychmiastowo kończy działanie. Zachowanie to nie może zostać zmienione, a proces nie ma możliwości zapisania swoich danych, więc są one tracone.

SIGTERM[edytuj]

Podstawowy sygnał do zabijania procesów. Ma numer 15, a jego nazwa pochodzi od angielskiego słowa termination. Po jego odebraniu proces może zdecydować, co ma robić - może natychmiastowo zakończyć działanie, zapisać dane i zakończyć lub całkowicie zignorować sygnał (w przeciwieństwie do SIGKILL i SIGQUIT).

Komenda kill domyślnie wysyła ten sygnał.

SIGQUIT[edytuj]

Sygnał używany do zabijania procesów siłą przy użyciu klawatury. Ma numer 3. Jest wysyłany do aplikacji poprzez wciśnięcie ^/ w czasie, gdy jest ona otwarta w ekranie termiala. Podobnie, jak SIGKILL nie może zostać zignorowany.