Wątki, sygnały i szeregowanie w systemach UNIX, Linux

Transkrypt

Wątki, sygnały i szeregowanie w systemach UNIX, Linux
SOE – Systemy Operacyjne
Wykład 6
Wątki, sygnały i szeregowanie
w systemach UNIX, Linux
dr inż. Andrzej Wielgus
Instytut Mikroelektroniki i Optoelektroniki
WEiTI PW
Systemy operacyjne
Andrzej Wielgus IMiO
Wątki w systemie Solaris
• Modele implementacji wątków
Ø model mieszany
Ø model 1-1
Systemy operacyjne
- do Solaris 8 włącznie
- Solaris 8, 9 i 10
Andrzej Wielgus IMiO
Wątki w systemie Solaris
• Wątki jądra
Ø podstawowe obiekty jądra
– niezależnie szeregowane i wykonywane równolegle na wielu
procesorach
– realizują wewnętrzne funkcje jądra (np. usługi systemowe)
– wspierają wykonywanie procesów lekkich
Ø atrybuty wątku
–
–
–
–
–
Systemy operacyjne
zawartość rejestrów z poziomu jądra
informacje o priorytecie i algorytmie szeregowania
wskaźniki do sąsiednich wątków w kolejce
wskaźnik do stosu
wskaźniki do związanych struktur lwp i proc
Andrzej Wielgus IMiO
Wątki w systemie Solaris
• Procesy lekkie (lightweight process - LWP)
Ø wspierany przez jądro wątek z poziomu użytkownika
Ø interfejs pomiędzy wątkami użytkownika i wątkami jądra
– każdy proces lekki może obsługiwać jeden lub kilka wątków
użytkownika w ramach jednego procesu
– każdy proces lekki jest związany z własnym wątkiem jądra
Ø atrybuty procesu lekkiego
–
–
–
–
–
–
–
Systemy operacyjne
identyfikator
zawartość rejestrów
informacje o sposobie obsługi sygnałów
informacje o zużyciu zasobów
budziki czasu wirtualnego
wskaźnik do struktury związanego wątku jądra
wskaźnik do struktury procesu proc
Andrzej Wielgus IMiO
Wątki w systemie Solaris
• Wątki użytkownika
Ø zarządzane przez bibliotekę wątków, bez udziału jądra
– tworzenie i usuwanie, szeregowanie, synchronizacja
Ø obsługiwane przez procesy lekkie
– wątek związany - związany na stałe z procesem lekkim
– wątek niezwiązany - współdzieli pulę procesów lekkich w
procesie
Ø atrybuty wątku
–
–
–
–
–
–
Systemy operacyjne
identyfikator
zawartość rejestrów
stos użytkownika, przydzielony przez bibliotekę
priorytet
maska blokowanych sygnałów
dane prywatne wątku, zarządzane przez bibliotekę
Andrzej Wielgus IMiO
Wątki w systemie Solaris
Proces 1
Proces 2
L
L
L
Proces 3
L
L
jądro
CPU
Systemy operacyjne
CPU
CPU
Andrzej Wielgus IMiO
Szeregowanie w systemie Solaris
• Koncepcja wielopoziomowego planowania kolejek
• Szeregowaniu podlegają wątki jądra a nie procesy
• Klasy szeregowania
Ø lokalne priorytety w klasie
Ø algorytm szeregowania w klasie
• Globalne szeregowanie priorytetowe
Ø globalne priorytety 0 - 169
Ø wybór wątku o najwyższym priorytecie
Ø wywłaszczanie
Systemy operacyjne
Andrzej Wielgus IMiO
Klasy szeregowania
Klasa
Priorytety
Kategoria wątków
szeregowania globalne
sprzętowe
160-169 wątki przerwań
RT
100-159
SYS
60-99
wątki systemowe jądra
IA
0-59
wątki interaktywne
TS
0-59
wątki w klasie z podziałem czasu
FX
0-59
FSS
0-59
Systemy operacyjne
wątki czasu rzeczywistego
Andrzej Wielgus IMiO
Klasy szeregowania
• Klasa RT (wątki czasu rzeczywistego)
Ø algorytmy szeregowania: FCFS lub RR
Ø wywłaszczanie
• Klasa SYS (wątki systemowe)
Ø szeregowanie priorytetowe
• Klasa TS (wątki z podziałem czasu)
Ø szeregowanie priorytetowe z kwantem czasu
Ø kwant czasu odwrotnie proporcjonalny do priorytetu
Ø postarzanie - obniżanie priorytetu po wyczerpaniu
kwantu czasu
Systemy operacyjne
Andrzej Wielgus IMiO
Informacje o parametrach szeregowania
ps -c[opcje]
dispadmin -l
dispadmin -c klasa
-g
[-r rozdzielczosc]
priocntl -l
priocntl -d [-i typ_id] [lista]
Systemy operacyjne
Andrzej Wielgus IMiO
Modyfikacja parametrów szeregowania
dispadmin -c klasa
-s plik
priocntl -s [-c klasa] [opcje] [-i typ_id ] [ lista]
priocntl -e [-c klasa] [opcje] cmd [arg…]
Systemy operacyjne
Andrzej Wielgus IMiO
Wątki w systemie Linux
• Model 1-1
• Procesy i wątki traktowane identycznie przez jądro
• Funkcja clone() tworzy nowy proces tradycyjny lub wątek
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg);
Ø argumenty wywołania określają zakres współdzielenia
zasobów
Systemy operacyjne
Andrzej Wielgus IMiO
Szeregowanie w systemie Linux (jądro 2.4)
• Koncepcja wielopoziomowego planowania kolejek
• 2 kategorie procesów
Ø procesy zwykłe
Ø procesy czasu rzeczywistego
• Atrybuty planowania
Ø
Ø
Ø
Ø
policy
- algorytm szeregowania
rt_priority - priorytet statyczny
priority
- początkowy priorytet dynamiczny
counter
- czas procesora przyznany procesowi,
używany jako priorytet dynamiczny procesu
Systemy operacyjne
Andrzej Wielgus IMiO
Szeregowanie w systemie Linux (jądro 2.4)
• Szeregowanie priorytetowe z wywłaszczaniem
Ø priorytet efektywny - waga procesu
– waga = 1000 + rt_priority - procesy RT
– waga = counter
- procesy zwykłe
• Procesy czasu rzeczywistego
Ø rt_priority > 0
Ø algorytmy szeregowania: FCFS lub RR
Systemy operacyjne
Andrzej Wielgus IMiO
Szeregowanie w systemie Linux (jądro 2.4)
• Procesy zwykłe
Ø rt_priority = 0
Ø planowanie priorytetowe z przyznawanym czasem
procesora
Ø wartość początkowa
– counter = priority
Ø w każdym takcie zegara
– counter = counter -1
Ø ponowne przeliczenie priorytetów, gdy counter = 0 dla
wszystkich procesów gotowych
– counter = counter/2 + priority
– mechanizm postarzania procesów
Systemy operacyjne
Andrzej Wielgus IMiO
Szeregowanie w systemie Linux (jądro 2.6.8)
• Atrybuty planowania procesu
Ø
Ø
Ø
Ø
static_prio
prio
sleep_avg
timeslice
- priorytet statyczny
- priorytet dynamiczny
- miara czasu uśpienia
- przydział czasu procesora
• Ustawianie priorytetu statycznego
Ø
Ø
Ø
Ø
domyślna wartość początkowa: static_prio = 0
ustawiona przez użytkownika: static_prio = nice
zakres wartości nice: <-20, 19>
ustawianie wartości nice
– funkcja systemowa nice()
– polecenia nice i renice
Systemy operacyjne
Andrzej Wielgus IMiO
Szeregowanie w systemie Linux (jądro 2.6.8)
• Ustawianie priorytetu dynamicznego
Ø
Ø
Ø
Ø
Ø
bonus lub kara za korzystanie z procesora
tylko procesy zwykłe (nie RT)
CURRENT_BONUS = sleep_avg * MAX_BONUS / MAX_SLEEP_AVG
bonus = CURRENT_BONUS – MAX_BONUS / 2
prio = static_prio – bonus
• Obliczanie przydziału czasu procesora
Ø na podstawie priorytetu statycznego
Ø timeslice = MIN_TIMESLICE + (MAX_TIMESLICE – MIN_TIMESLICE)
* (MAX_PRIO – 1 – static_prio) / MAX_USER_PRIO -1
Systemy operacyjne
Andrzej Wielgus IMiO
Szeregowanie w systemie Linux (jądro 2.6.8)
• Kolejki procesów gotowych przydzielonych do
poszczególnych procesorów
Ø oddzielna kolejka na każdego CPU
Ø wskaźniki na dwie tablice priorytetów
prio_array_t *active
– procesy aktywne, które nie wyczerpały jeszcze swoich
przydziałów czasu procesora
prio_array_t *expired
– procesy, które wyczerpały już swoje przydziały czasu procesora
Systemy operacyjne
Andrzej Wielgus IMiO
Szeregowanie w systemie Linux (jądro 2.6.8)
• Tablica priorytetów
unsigned int nr_active
– liczba aktywnych procesów
unsigned long bitmap[BITMAP_SIZE]
– bitmapa priorytetów
struct list_head queue[MAX_PRIO]
– tablica list procesów dla poszczególnych wartości priorytetu
Systemy operacyjne
Andrzej Wielgus IMiO
Szeregowanie w systemie Linux (jądro 2.6.8)
• Funkcja scheduler_tick()
Ø uruchamiana po każdym przerwaniu zegarowym
Ø sprawdza, czy proces wyczerpał swój przydział czasu
procesora
• Funkcja schedule()
Ø główna funkcja szeregowania procesów
Ø uruchamiana, gdy:
– proces zwalnia CPU w wyniku wywołania funkcji systemowej
– proces wyczerpał przydział czasu procesora - stwierdzone
przez scheduler_tick()
• Złożoność obliczeniowa O(1)
Systemy operacyjne
Andrzej Wielgus IMiO
Standardy implementacji biblioteki wątków
• POSIX - standard POSIX IEEE Std 1003.1:1996 i
IEEE Std 1003.1:2001
Ø opisuje interfejs programowania wielowątkowego w
systemach uniksowych
Ø biblioteka funkcji: libpthread
– funkcje pthread_xxx
• Solaris - standard UI (UNIX International)
Ø opracowany dla systemu Solaris z uwzględnieniem
specyfiki jego implementacji modelu m-n
Ø biblioteka funkcji: libthread
– funkcje thr_xxx
Systemy operacyjne
Andrzej Wielgus IMiO
Podstawowe operacje na wątkach (POSIX)
•
•
•
•
•
Tworzenie wątku
Pobieranie i modyfikacja atrybutów
Kończenie wątku
Oczekiwanie na zakończenie wątku
Odłączanie wątku
Systemy operacyjne
Andrzej Wielgus IMiO
Tworzenie wątku
int pthread_create(pthread_t *thread,
pthread_attr_t *attr,
void *(*start_func)(void *),
void *arg);
Ø tworzy nowy wątek z domyślnym zestawem atrybutów
Ø zwraca identyfikator przez thread
Ø nowy wątek działa współbieżnie z wątkiem bieżącym
(wołającym funkcję)
Ø nowy wątek wykonuje podaną funkcję start_func()
z argumentem arg
Systemy operacyjne
Andrzej Wielgus IMiO
Atrybuty wątku
Atrybut
scope
Wartości
Znaczenie
PTHREAD_SCOPE_PROCESS
wątek szeregowany na poziomie
procesu, nie związany na stałe z
procesem lekkim LWP (unbound)
PTHREAD_SCOPE_SYSTEM
wątek szeregowany na poziomie jądra,
związany na stałe z procesem lekkim
LWP (bound)
detachstate PTHREAD_CREATE_JOINABLE
(domyślnie)
wątek dołączalny, inne wątki mogą
oczekiwać na jego zakończenie i
odebrać status (synchronizować się)
PTHREAD_CREATE_DETACHED wątek odłączony, inne wątki nie mogą
oczekiwać na jego zakończenie
(synchronizować się)
Systemy operacyjne
Andrzej Wielgus IMiO
Atrybuty wątku c.d.
Atrybut
Wartości
Znaczenie
stackaddr
NULL (domyślnie)
adres początkowy stosu (domyślnie:
stos alokowany przez system)
stacksize
NULL (domyślnie)
rozmiar stosu (domyślnie: 1 MB)
schedpolicy
SCHED_OTHER (domyślnie) planowanie priorytetowe
SCHED_FIFO
planowanie FCFS
SCHED_RR
planowanie rotacyjne RR
schedparam
parametry szeregowania wątku
inheritsched PTHREAD_EXPLICIT_SCHED parametry szeregowania ustawiane na
podstawie argumentów wywołania
funkcji pthread_create()
PTHREAD_INHERIT_SCHED
Systemy operacyjne
parametry szeregowania dziedziczone
po procesie macierzystym
Andrzej Wielgus IMiO
Kończenie wątku
• Powrót z wykonywanej funkcji start_func()
• Zakończenie procesu poprzez _exit()
• Wywołanie funkcji pthread_exit()
void pthread_exit(void *retval);
Ø wątki dołączalne - zasoby pamięci zwalniane po
odebraniu statusu przez inny wątek
Ø wątki odłączone - zasoby pamięci są zwalniane
natychmiast
Systemy operacyjne
Andrzej Wielgus IMiO
Oczekiwanie na zakończenie wątku
int pthread_join(pthread_t thread,
void **thread_return);
Ø wstrzymuje wołający wątek do momentu zakończenia
wątku wskazanego przez thread
Ø zwraca status zakończenia
int pthread_detach(pthread_t thread);
Ø odłącza wskazany wątek
Systemy operacyjne
Andrzej Wielgus IMiO
Przykład 1 – 1 wątek roboczy
/* Silberschatz, Galvin and Gagne: Operating System Concepts, 2003 */
/* modyfikacje: A. Wielgus */
#include <pthread.h>
int sum;
/* zmienna współdzielona przez wątki */
void *runner(void *param); /* funkcja wątku */
main(int argc, char *argv[]) {
pthread_t tid;
/* identyfikator wątku */
pthread_attr_t attr; /* zbiór atrybutów */
Systemy operacyjne
Andrzej Wielgus IMiO
Przykład 1 – 1 wątek roboczy
/* pobranie domyślnych atrybutów */
pthread_attr_init(&attr);
if (argc != 2){
printf("Niewłaściwa liczba argumentów\n");
exit(1);
}
/* tworzenie wątku */
if (pthread_create(&tid,&attr,runner,argv[1]))
perror("pthread_create");
/* oczekiwanie na zakończenie wątku */
if (pthread_join(tid,NULL))
perror("pthread_join");
printf("sum = %d\n",sum);
}
Systemy operacyjne
Andrzej Wielgus IMiO
Przykład 1 – 1 wątek roboczy
/* funkcja wątku */
void* runner(void*param) {
int upper = atoi(param);
int i;
sum = 0;
if (upper > 0) {
for (i = 1; i <= upper; i++)
sum += i;
}
pthread_exit(0);
}
Systemy operacyjne
Andrzej Wielgus IMiO
Przykład 2 – wiele wątków roboczych
#include <pthread.h>
#define N 10
void *runner(void *param);
/* funkcja watku roboczego */
main(int argc, char *argv[])
{
pthread_t tid[N];
/* tablica identyfikatorow watkow */
pthread_attr_t attr;
/* zbior atrybutow watkow */
int i, *stat[N];
if (argc > N+1) {
printf("Nieprawidlowa liczba argumentow\n");
exit(1);
}
Systemy operacyjne
Andrzej Wielgus IMiO
Przykład 2 – wiele wątków roboczych
/* get the default attributes */
pthread_attr_init(&attr);
/* tworzenie watkow roboczych - jeden watek na kazdy
argument wywolania */
for (i=1; i<argc; i++) {
if (pthread_create(&tid[i-1],&attr,runner,argv[i]))
perror("watek");
}
/* oczekiwanie na zakonczenie watkow roboczych */
for (i=1; i<argc; i++) {
pthread_join(tid[i-1],(void**)&(stat[i-1]));
printf("pid=%d tid=%d ",getpid(), pthread_self());
printf("sum(%d) = %d\n", atoi(argv[i]), *stat[i-1]);
}
}
Systemy operacyjne
Andrzej Wielgus IMiO
Przykład 2 – wiele wątków roboczych
void *runner(void *param) {
int upper = atoi(param);
int i;
int sum;
sum = 0;
if (upper > 0) {
for (i = 1; i <= upper; i++)
sum += i;
}
printf("pid=%d tid=%d sum = %d\n",getpid(),
pthread_self(), sum);
pthread_exit(&sum);
}
Systemy operacyjne
Andrzej Wielgus IMiO
Proces a wątek
• Tradycyjny proces – proces jednowątkowy
• Rozwidlanie procesu wielowątkowego:
Ø powielanie wszystkich wątków
– funkcja fork() (Solaris)
Ø powielanie tylko wątku wołającego
– funkcja fork() (POSIX)
– funkcja fork1()
Systemy operacyjne
Andrzej Wielgus IMiO
Tworzenie programów wielowątkowych
• Wątki POSIX
Ø Plik nagłówkowy
– #include <pthread.h>
Ø Makrodefinicja
– #define _REENTRANT
– -D _REENTRANT
Ø Wywołanie kompilatora
gcc [opcje... ] plik ... –lpthread ...
Systemy operacyjne
Andrzej Wielgus IMiO
Przesyłanie i obsługa sygnałów
•
Sygnały
•
Obsługa sygnałów w procesach
•
Obsługa sygnałów w wątkach
Systemy operacyjne
Andrzej Wielgus IMiO
Sygnały
• Sygnał – asynchroniczna informacja dla procesu o
zajściu zdarzenia
• Generacja sygnałów
Ø
Ø
Ø
Ø
Ø
wyjątki (przerwania programowe)
przerwania z terminala (ctrl c, ctrl \, ctrl z)
inne procesy
powiadomienia (zakończenie operacji we-wy)
budziki
Systemy operacyjne
Andrzej Wielgus IMiO
Przegląd wybranych sygnałów
Nazwa
sygnału
Numer
sygnału
SIGHUP
1
Zerwanie połączenia z
terminalem sterującym
Zakończenie procesu
SIGINT
2
Przerwanie
Zakończenie procesu
SIGQUIT
3
Zakończenie procesu
Zakończenie procesu i zrzut
obrazu pamięci do pliku core
SIGILL
4
Nielegalna instrukcja w
kodzie
Zakończenie procesu
SIGKILL
9
Zabicie procesu
Bezwzględne zakończenie
procesu
SIGSEGV
11
Przekroczenie
dopuszczalnego adresu
pamięci
Zakończenie procesu
SIGALRM
14
Alarm programowy
Ignorowanie
SIGTERM
15
Przerwanie programowe
Zakończenie procesu
Systemy operacyjne
Znaczenie
Domyślna reakcja procesu
Andrzej Wielgus IMiO
Przegląd wybranych sygnałów
Nazwa
sygnału
Znaczenie
Domyślna reakcja
procesu
SIGCONT
Wznowienie
wykonywania procesu
Wznowienie wykonywania
procesu
SIGSTOP
Bezwzględne
zatrzymanie procesu
Bezwzględne wstrzymanie
wykonywania procesu
SIGTSTP
Zatrzymanie procesu w
wyniku wprowadzenie z
terminala sekwencji Ctrl-z
Wstrzymanie
wykonywania procesu
SIGCHLD
Numer
sygnału
zależny od
implementacji Informacja o zakończeniu
(śmierci) procesu
potomnego
Ignorowanie
SIGUSR1
Sygnał definiowany przez
użytkownika
Niezdefiniowana
SIGUSR2
Sygnał definiowany przez
użytkownika
Niezdefiniowana
Systemy operacyjne
Andrzej Wielgus IMiO
Obsługa sygnałów w procesach
• Sprawdzanie nadesłanych sygnałów
Ø maska nadesłanych sygnałów (w strukturze proc)
Ø tylko proces wykonywany może obsłużyć sygnały
– przed powrotem do trybu użytkownika z funkcji systemowej
lub obsługi przerwania
– tuż przed uśpieniem lub tuż po obudzeniu procesu
• Sposoby obsługi
Ø
Ø
Ø
Ø
domyślna
ignorowanie
własna funkcja obsługi
wyjątki: SIGKILL i SIGSTOP
Systemy operacyjne
Andrzej Wielgus IMiO
Obsługa sygnałów w procesach
• Blokowanie sygnałów
Ø maska blokowanych sygnałów (w strukturze proc)
Ø jądro przechowuje informacje o nadesłanych sygnałach
Ø wyjątki: SIGKILL i SIGSTOP
Systemy operacyjne
Andrzej Wielgus IMiO
Obsługa sygnałów w wątkach
• Wspólne funkcje obsługi sygnałów (ustawione dla
wszystkich wątków w procesie)
• Odrębne maski blokowanych sygnałów
• Sygnały spowodowane przez pułapki
(SIGILL, SIGSEGV itp.)
Ø obsługiwane przez wątek, który spowodował pułapkę
• Sygnały spowodowane przez przerwania czyli
zdarzenia zewnętrzne (SIGIO, SIGINT itp.)
Ø obsługiwane przez jeden dowolny wątek, którego
maska na to pozwala
Ø następny sygnał, w trakcie obsługi poprzedniego,
obsługiwany przez następny wątek
Systemy operacyjne
Andrzej Wielgus IMiO
Wysyłanie sygnałów do procesu
int kill(pid_t pid, int sig);
• Wysyła sygnał sig do procesu lub grupy procesów:
Ø pid > 0 - do procesu o identyfikatorze pid
Ø pid = 0 - do wszystkich procesów w grupie
procesu wysyłającego
Ø pid = -1 - do wszystkich procesów w systemie z
wyjątkiem procesu init (PID=1)
Ø pid < -1 - do wszystkich procesów w grupie o
identyfikatorze pgid = -pid
Systemy operacyjne
Andrzej Wielgus IMiO
Wysyłanie sygnałów do wątków
int pthread_kill(pthread_t thread, int sig);
• Wysyła sygnał do wskazanego wątku w tym samym procesie
Systemy operacyjne
Andrzej Wielgus IMiO
Ustawianie obsługi
int sigaction(int sig, const struct sigaction *act,
struct sigaction *oact);
struct sigaction {
void (*sa_handler)(int); - sposób obsługi sygnału
sigset_t sa_mask;
- maska sygnałów blokowanych
int sa_flags;
- flagi
}
• Ustawia sposób obsługi sygnału sig przez sa_handler:
Ø SIG_DFL – obsługa domyślna
Ø SIG_IGN – ignorowanie
Ø wskaźnik do własnej funkcji obsługi (nazwa funkcji)
• Blokuje sygnał sig oraz inne sygnały sa_mask na czas
obsługi
Systemy operacyjne
Andrzej Wielgus IMiO
Ustawianie obsługi
• Ustawienie obsługi jednokrotne
void (*signal(int sig, void (*handler)(int)))(int);
• Ustawienie obsługi na stałe (do odwołania)
void (*sigset(int sig, void (*handler)(int)))(int);
Systemy operacyjne
Andrzej Wielgus IMiO
Ustawianie maski blokowanych sygnałów
int sigprocmask(int how, const sigset_t *set,
sigset_t *oset);
int pthread_sigmask(int how, const sigset_t *set,
sigset_t *oset);
• Ustawia lub pobiera maskę blokowanych sygnałów w wątku
w zależności od wartości argumentu how:
Ø
Ø
Ø
Ø
SIG_BLOCK
- dodaje zbiór sygnałów set do maski
SIG_UNBLOCK
- usuwa zbiór sygnałów set z maski
SIG_SETMASK
- ustawia zbiór sygnałów set jako maskę
jeśli set==NULL, funkcja tylko zapisuje aktualną maskę w oset
Systemy operacyjne
Andrzej Wielgus IMiO
Ustawianie maski blokowanych sygnałów
• Operacje na masce
int
int
int
int
int
Systemy operacyjne
sigemptyset(sigset_t *set);
sigfillset(sigset_t *set);
sigaddset(sigset_t *set, int signo);
sigdelset(sigset_t *set, int signo);
sigismember(sigset_t *set, int signo);
Andrzej Wielgus IMiO
Uzyskanie informacji o niezałatwionych sygnałach
int sigpending(sigset_t *set);
Ø Pobiera zbiór niezałatwionych sygnałów set, które
zostały wysłane do procesu, ale ich dostarczenie było
zablokowane
Ø Funkcja sigismember() pozwala zbadać obecność
konkretnego sygnału w zbiorze set
Systemy operacyjne
Andrzej Wielgus IMiO
Wstrzymywanie procesu w oczekiwaniu na sygnał
int pause(void);
Ø Funkcja wstrzymuje proces w oczekiwaniu na sygnał
int sigsuspend(const sigset_t *mask);
Ø Funkcja podmienia maskę blokowanych sygnałów na mask
i wstrzymuje proces w oczekiwaniu na sygnał
int sigwait(sigset_t *set);
int sigwait(const sigset_t *set, int *sig);
Ø Funkcja pobiera jeden niezałatwiony sygnał ze zbioru set lub
wstrzymuje wątek w oczekiwaniu na sygnał ze zbioru. Pobrany
sygnał jest usuwany ze zbioru sygnałów niezałatwionych, a numer
sygnału jest zwracany jako wartość funkcji lub zapisywany w sig.
Działanie funkcji jest niezależne od maski blokowanych sygnałów,
czyli wątek może czekać synchronicznie na sygnał.
Systemy operacyjne
Andrzej Wielgus IMiO
Przykład – sygnały w procesie jednowątkowym (1)
#include
#include
#include
#include
#include
<stdio.h>
<unistd.h>
<sys/types.h>
<signal.h>
<errno.h>
void Obsluga(int);
int licznik;
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");
sigdelset(&maska, SIGINT);
Systemy operacyjne
Andrzej Wielgus IMiO
Przykład – sygnały w procesie jednowątkowym (2)
while(1)
sigsuspend(&maska);
return(0);
}
void Obsluga(int numerSygnalu)
{
licznik++;
printf("Odebralem %d sygnal SIGINT (%d).\n", licznik,
numerSygnalu);
}
Systemy operacyjne
Andrzej Wielgus IMiO
Obsługa sygnałów
• Obsługa asynchroniczna
Ø ustawienie funkcji obsługi sygnału w procesie
– sigaction()
– wykonuje dowolny wątek (zwykle główny)
– dotyczy wszystkich wątków
Ø można ustawić blokowanie sygnałów poza jednym
wybranym wątkiem
• Obsługa synchroniczna
Ø zablokowanie sygnałów we wszystkich wątkach
Ø w wybranym wątku:
– sigwait()
– obsługa sygnału bezpośrednio w kodzie
Systemy operacyjne
Andrzej Wielgus IMiO
Funkcje obsługi sygnałów - zalecenia
• Stosować wywołania funkcji bezpiecznych przy
obsłudze sygnałów (ang. Async-Signal-Safe)
Ø atrybut MT-level w man
• Stosować bezpieczne typy zmiennych globalnych
(o dostępie atomowym)
Ø volatile sig_atomic_t
Ø typ integer oraz wskaźniki można uznać za
bezpieczne
Systemy operacyjne
Andrzej Wielgus IMiO
Odmierzanie czasu
• Budziki systemowe dla procesu
Ø ITIMER_REAL - budzik czasu rzeczywistego
– odmierza czas rzeczywisty
– sygnał SIGALRM
Ø ITIMER_VIRTUAL - budzik czasu wirtualnego
– odmierza czas wykonywania procesu w trybie użytkownika
– sygnał SIGVTALRM
Ø ITIMER_PROF - budzik profilowania
– odmierza czas wykonywania procesu w trybie użytkownika i
w trybie jądra
– sygnał SIGPROF
Ø ITIMER_REALPROF - budzik profilowania czasu
rzeczywistego
Systemy operacyjne
Andrzej Wielgus IMiO
Odmierzanie czasu
int getitimer(int which, struct itimerval *value);
int setitimer(int which, const struct itimerval
*value, struct itimerval *ovalue);
Ø Odczytuje lub ustawia jeden z budzików
unsigned int alarm(unsigned int sec);
int usleep(useconds_t useconds);
Ø W procesach jednowątkowych ustawia budzik czasu
rzeczywistego procesu
Ø W procesach wielowątkowych -> nanosleep()
int nanosleep(const struct timespec *rqtp, struct
timespec *rmtp);
Ø Usypia bieżący wątek
Systemy operacyjne
Andrzej Wielgus IMiO
Odmierzanie czasu
struct
itimerval {
struct timeval it_interval; /* timer interval */
struct timeval it_value;
/* current value */
};
struct timeval {
time_t
suseconds_t
};
timespec {
time_t
long
} timespec_t;
tv_sec;
tv_usec;
/* seconds */
/* microseconds */
tv_sec;
tv_nsec;
/* seconds */
/* nanoseconds */
struct
Systemy operacyjne
Andrzej Wielgus IMiO