Linux Wiki
linuxwiki.pl>PiotrekD.bot
m (Szablon:T jest wycofywany z użycia)
 
Nie podano opisu zmian
 
Linia 1: Linia 1:
  +
'''Sygnały''' – jeden z podstawowych sposobów komunikacji międzyprocesowej w systemach uniksowych, w tym również w [[GNU/Linux|Linuksie]].
{{małą literą}}
 
{{stub}}
 
{{Infobox dystrybucja
 
| logo = [[Plik:OpenSUSE - logo.svg|75px|Logo dystrybucji]]
 
| producent = openSUSE Project
 
| www = http://opensuse.org/
 
| 1 wydanie = 7 grudnia 2006<ref>Wersja 10.2, pierwsza pod nazwą openSUSE.</ref>
 
| wersja stabilna = 12.3
 
| wersja rozwojowa = 13.1
 
| pakiety = [[RPM]]
 
| menedżer pakietów = [[ZYpp]] ([[YaST]], [[zypper]])
 
| platforma = x86, AMD64
 
| środowisko = Głównie [[KDE]] i [[GNOME]]
 
| live = Dostępna
 
}}
 
'''OpenSUSE''' – dystrybucja [[GNU/Linux|Linuksa]], powstała po podziale SUSE Linux na dystrybucję społecznościową i komerycyjną.
 
   
  +
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.
Dystrybucja ta przeznaczona jest głównie na komputery typu desktop. Jej głównymi środowiskami graficznymi są [[KDE]] i [[GNOME]] (z czego podczas instalacji domyślnie wybrane jest to pierwsze).
 
   
  +
== Wysyłanie sygnałów ==
openSUSE używa pakietów [[RPM]], zarządzanych głównie silnikiem [[ZYpp]]. Charakterystyczną cechą dystrybucji jest jej narzędzie konfiguracyjne [[YaST]], umożliwiające administrowanie zaawansowanymi funkcjami systemu poprzez interfejs graficzny.
 
   
  +
=== Z poziomu poleceń terminala ===
{{Przypisy}}
 
  +
Do wysyłania sygnałów z poziomu konsoli służy polecenie <code>[[kill]]</code>. Jej użycie ma postać
  +
<terminal>
  +
$ kill [przełączniki] <PID> {{...|identyfikatory wielu procesów}}
  +
</terminal>
  +
Jeśli nie podane zostaną żadne przełączniki zostanie wysłany sygnał <code>SIGTERM</code>. Aby wysłać inny sygnał, wystarczy podać go poprzedzonego myślnikiem (<code>-</code>). Przykładowo, wysłanie sygnału <code>SIGUSR1</code> o wartości 10 do procesu o numerze 1234, wygląda tak:
  +
<terminal>
  +
$ kill -10 1234
  +
</terminal>
   
  +
=== Z poziomu programu ===
[[Kategoria:Dystrybucje]]
 
  +
Wysłanie sygnału z poziomu programu jest możliwe dzięki wywołaniu systemowemu <code>kill()</code>. 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 <code><signal.h></code>), 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 <code>SIGUSR1</code> do procesu o numerze 1234, wygląda tak:
  +
<source lang="c">
  +
kill(10, 1234);
  +
</source>
  +
lub, by użyciu makr z nazwami (wymaga załączenia <code><signal.h></code>):
  +
<source lang="c">
  +
kill(SIGUSR1, 1234);
  +
</source>
  +
  +
== Obsługa sygnałów ==
  +
Za obsługę sygnałów odpowiada wywołanie systemowe <code>signal()</code>. 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ł <code>SIGUSR1</code>. Po jego otrzymaniu wyświetli odpowiednią informację i zakończy działanie.
  +
<source lang="c">
  +
#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;
  +
}
  +
</source>
  +
  +
Wyjście programu, po umieszczeniu tekstu w pliku <code>program.c</code>, wykonaniu trzech poleceń i wysłaniu po tym signału <code>SIGUSR1</code> dowolnym sposobem:
  +
<terminal>
  +
$ gcc program.c -o program
  +
$ chmod +x program
  +
$ ./program
  +
Mam SIGUSR1.
  +
Kończę pracę...
  +
</terminal>
  +
  +
== Standardowe sygnały ==
  +
  +
=== <code>SIGCHLD</code> ===
  +
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.
  +
  +
=== <code>SIGFPE</code> ===
  +
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ć.
  +
  +
=== <code>SIGKILL</code> ===
  +
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.
  +
  +
=== <code>SIGTERM</code> ===
  +
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 <code>SIGKILL</code> i <code>SIGQUIT</code>).
  +
  +
Komenda <code>[[kill]]</code> domyślnie wysyła ten sygnał.
  +
  +
=== <code>SIGQUIT</code> ===
  +
Sygnał używany do zabijania procesów siłą przy użyciu klawatury. Ma numer '''3'''. Jest wysyłany do aplikacji poprzez wciśnięcie {{ctrl|/}} w czasie, gdy jest ona otwarta w ekranie termiala. Podobnie, jak <code>SIGKILL</code> nie może zostać zignorowany.
  +
  +
[[Kategoria:Komunikacja międzyprocesowa]]

Wersja z 12:07, 9 lis 2017

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

Z poziomu poleceń terminala

Do wysyłania sygnałó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 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

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>

Standardowe sygnały

SIGCHLD

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

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

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

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

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.