Sygnały – jeden z podstawowych i 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
Z poziomu poleceń terminala
Do wysyłania procesów z poziomu konsoli służy polecenie kill
. Jej użycie ma postać
<terminal>
$ kill [przełączniki] <PID> ...
</terminal>
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:
<terminal>
$ kill -10 1234
</terminal>
Z poziomu programu
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 zostać zabity. Umożliwia zabicie tylko jednego procesu 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
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
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:
<terminal>
$ gcc program.c -o program
$ chmod +x program
$ ./program
Mam SIGUSR1.
Kończę pracę...
</terminal>