2. Obsługa sygnałów

Dokument: pdf (143.1 KB)
  • 4 stron
Opublikowany 2017-07-23 02:06:09

29.03.2017, 01*05Systemy Operacyjne - Lekcja 6 - Segment 1 Strona 1 z 4http://oldwww.imio.pw.edu.pl/wwwvlsi/cad/teaching/soe/materialy/LEKCJA6/SEGMENT2/MAIN.HTM 2. Obsługa sygnałów w procesie (2.1) Funkcje systemowe Funkcja kill() umożliwia wysyłanie sygnałów do procesów. int kill(pid_t pid, int sig); gdzie: pid - identyfikator PID procesu, sig - numer lub nazwa sygnału. Argument pid może przyjąć jedną z następujących wartości: pid > 0 Sygnał wysyłany jest do procesu o identyfikatorze pid pid = 0 Sygnał wysyłany jest do wszystkich procesów w grupie procesu wysyłającego pid = -1 Sygnał wysyłany jest do wszystkich procesów w systemie z wyjątkiem procesu init (PID=1) pid < -1 Sygnał wysyłany jest do wszystkich procesów w grupie o identyfikatorze pgid = -pid Funkcje signal() i sigaction() umożliwiają zmianę domyślnego sposobu obsługi sygnałów w procesie. Pozwalają zdefiniować własną funkcję obsługi lub spowodować, że sygnały będą ignorowane. Oczywiście obowiązuje tu ograniczenie, podane w lekcji 2, że sygnały SIGKILL i SIGSTOP zawsze są obsługiwane w sposób domyślny. Funkcja signal() ma zdecydowanie prostszą składnię: void (*signal(int signum, void (*sighandler)(int)))(int); gdzie: signum - numer sygnału, sighandler - sposób obsługi sygnału. Ustawia jednak tylko jednokrotną obsługę wskazanego sygnału, ponieważ jądro przywraca ustawienie SIG_DFL przed wywołaniem funkcji obsługującej sygnał. Argument sighandler może przyjąć jedną z następujących wartości: SIG_DFL, SIG_IGN, wskaźnik do własnej funkcji obsługi. Ustawienie SIG_DFL oznacza domyślną obsługę przez jądro. Wartość SIG_IGN oznacza ignorowanie 29.03.2017, 01*05Systemy Operacyjne - Lekcja 6 - Segment 1 Strona 2 z 4http://oldwww.imio.pw.edu.pl/wwwvlsi/cad/teaching/soe/materialy/LEKCJA6/SEGMENT2/MAIN.HTM sygnału. Funkcja sigaction() ma znacznie większe możliwości. Nie tylko zmienia obsługę sygnału na stałe (do następnej świadomej zmiany), ale również ustawia jego blokowanie na czas wykonywania funkcji obsługi. Pozwala ponadto zablokować w tym czasie inne sygnały. int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); gdzie: signum - numer sygnału, act - struktura typu sigaction opisująca nowy sposób obsługi, oldact - struktura typu sigaction przeznaczona do zapamiętania starego sposobu obsługi. Struktura sigaction zdefiniowana jest następująco: struct sigaction { void (*sa_handler) (int); - sposób obsługi sygnału sigset_t sa_mask; - maska sygnałów blokowanych na czas obsługi odebranego sygnału int sa_flags; - flagi void (*sa_restorer) (void); - pole nieużywane } Funkcja sigaction() blokuje wybrane sygnały jedynie na czas obsługi nadesłanego sygnału. Istnieje możliwość ustawienia maski blokowanych sygnałów na dowolnie długi okres aż do ponownej zmiany przy pomocy funkcji: int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); gdzie: how - sposób zmiany maski, set - zbiór sygnałów przeznaczony do zmiany aktualnej maski, oldset - zbiór sygnałów przeznaczony do zapamiętania starej maski. Argument how określa operację, jaka będzie wykonana na aktualnej masce blokowanych sygnałów i może przyjmować trzy wartości: 29.03.2017, 01*05Systemy Operacyjne - Lekcja 6 - Segment 1 Strona 3 z 4http://oldwww.imio.pw.edu.pl/wwwvlsi/cad/teaching/soe/materialy/LEKCJA6/SEGMENT2/MAIN.HTM SIG_BLOCK - sygnały ustawione w zbiorze set są dodawane do maski, SIG_UNBLOCK - sygnały ustawione w zbiorze set są usuwane z maski, SIG_SETMASK - wyłącznie sygnały ustawione w zbiorze set są ustawiane w masce. Sygnały blokowane nie są dostarczane do procesu, ale nie giną bezpowrotnie. Jądro przechowuje takie niezałatwione sygnały do momentu, gdy proces odblokuje ich odbieranie. Uzyskanie informacji o niezałatwionych sygnałach umożliwia funkcja: int sigpending(sigset_t *set); Proces może zawiesić swoje działanie w oczekiwaniu na sygnał. Funkcja pause() usypia proces do momentu nadejścia dowolnego sygnału. int pause(void); Z kolei funkcja sigsuspend() czasowo zmienia maskę blokowanych sygnałów i oczekuje na jeden z sygnałów, które nie są blokowane. Dzięki temu umożliwia oczekiwanie na konkretny sygnał poprzez zablokowanie wszystkich pozostałych. int sigsuspend(const sigset_t *mask); Przykład Prezentowany poniżej program demonstruje sposób zmiany standardowej procedury obsługi sygnału SIGINT na procedurę określoną przez programistę. #include #include #include #include #include void Obsluga(int); int main(void) { struct sigaction nowaAkcja; sigset_t maska; sigfillset(&maska); nowaAkcja.sa_handler = Obsluga; nowaAkcja.sa_mask = maska; if (sigaction(SIGINT, &nowaAkcja, NULL)) perror("Blad sigaction"); 29.03.2017, 01*05Systemy Operacyjne - Lekcja 6 - Segment 1 Strona 4 z 4http://oldwww.imio.pw.edu.pl/wwwvlsi/cad/teaching/soe/materialy/LEKCJA6/SEGMENT2/MAIN.HTM sigdelset(&maska, SIGINT); while(1) sigsuspend(&maska); return(0); } void Obsluga(int numerSygnalu) { printf("Odebralem sygnal SIGINT.\n"); } ...

Komentarze do: 2. Obsługa sygnałów • 0