OPERÁCIÓS RENDSZEREK Eseménykezelés, szignálozás
A mai program • Alapfogalmak: esemény, jelződés, kezelés • Megszakítások és kivételek • Szignálozás – Rendelkezés szignálról (SVID, POSIX) – Postázás
• Esettanulmányok
Vadász
2
Hiba és eseménykezelés. Alapfogalmak. • Esemény: folyamatok (taszk, processz, fonál, rutin, utasítás, instrukció) futását befolyásoló, váratlan időpontban bekövetkező történés, amire reagálni kell (le kell kezelni). • Feltétel állapot: egy állapottér állapotvektora. • Jelzés keletkezik, ha a feltétel - az esemény bekövetkezik. Jelződik az esemény. • A jelződés az alapja a lekezelhetőségnek: ami kapja a jelzést, az lekezelheti az eseményt. Vadász
3
1
Az esemény jelződik: lekezelhető • A lekezelés megváltoztatja a futás menetét: • a normális futás mentét abba kell hagyni (Instrukciót? Utasítást? Rutint? Fonalat? Processzt? Taszkot?) • Lekezelni instrukciófolyammal, rutinnal, fonállal, processzel. • Dönteni, visszaadható-e a vezérlés (instrukcióra, utasításra, rutinba/fonálba/processzbe; [elejére, végére], vagy utánuk?), vagy az OS-nek adjuk a vezérlést?
Vadász
4
Az események osztályai • Egy processz szemszögéből – belső esemény, – külső esemény.
• Előállítója szerint – HW által generált és detektált (IT, errors), – SW által generált és detektált: SWIT, SW által generált kivétel, felhasználói akciók).
• Lekezelési szintjük szerint – megszakítások (interrupts, IT), – kivételek (exeptions), – alkalmazás által kezelt események (felhasználói akciók). Vadász
5
Megszakítások • • • • •
A legalacsonyabb szintű események. Aszinkron. Külső. Előállítója rendszerint a HW, de lehet SW is. Lekezelői: az OS kernel IT handlerei. Kezelés módja: – aktuális instrukció befejeződik, – a lekezelő fut, – soron következő instrukcióra tér vissza.
• IT prioritási szintek vannak. • Le nem kezelt megszakítások HW-es sorokon várakoznak (pending ITs). Vadász
6
2
Kivételek, hibaesemények (exeptions) • Abnormális helyzetet, gondot jelentenek. Szinkron jellegűek, de váratlanok. • Lehetnek alacsony szintűek: túlcsordulás, • Lehetnek magas szintűek: pl. laphiba. Az alacsony, magas szint megmondja – minek szól a jelzés (instrukciónak, ... processznek), – a kezelés szintjét is.
• A klasszikus kivételnél: az entitás nem fejezhető be! Ha hatásosan lekezelhető, az entitás futását meg kell ismételni. • Az OS-ekben vannak alapértelmezési kezelők. A programozó is lekezelhet egyes kivételeket (értelmet nyer a magasabb jelző, veszít a hiba jelző) Vadász
7
Alkalmazás által kezelt események • Bekövetkezésüket a programozó eleve várja (de váratlanok időben). • Tipikus példa: X11 vagy más GUI-is. Alkalmazás eseményvezérelt programozása. Magas szintűek: – – – – –
Fejlesztő eszközök kellenek (RTL rutinok), programozó maszkolhatja őket, lekezelő rutinjait ő írja meg, az eseménysorokat figyelheti. Kezelésükhöz használhatja az IT- és kivétel-kezelési technikákat.
Vadász
8
Megszakítások versus kivételek • Az IT aszinkron. Két instrukció között kiszolgálódnak. • A kivétel váratlan, de szinkron (az adott instrukcióhoz tartozik). Tipikus a laphiba. • Az IT nem kapcsolódik a futó processzhez (kiszolgálása nem a futó processz javára). • A kivétel kiszolgálása “kiegészítése“ a processz instrukciófolyamának.
Vadász
9
3
Megszakítások - kivételek • Az IT kiszolgálásnál prioritási szintek. Maszkolás. Kiszolgálásuk is megszakítható. HW-es a sorképzés. • A kivételek kiszolgálását más kivétel nem szakíthatja meg. • IT kiszolgálásra lehet közös rendszer verem. • A kivétel kiszolgálására rendszerint processzenkénti kernel verem.
Vadász
10
A jelzés fogalom • Jelzés (signal) keletkezik feltétel állapot kialakulásakor (esemény bekövetkezésekor): a jelződés a fontos. • A tárgyalás ekkor: – – – – –
van egy jelzés készlet; jelzés keletkezik HW vagy SW eredetből. A jelzés kikézbesítődik (CPU-nak, processznek). A kikézbesített jelzések sorokban várhatnak lekezelésre. A kikézbesített jelzéseket e megfelelő kezelő (handler) lekezeli.
• Ez a szignál fogalom tágabb értelmezése. Vadász
11
Szignálozás: szűkebb értelem Bizonyos szignálokat az OS küld és kezel le; de mi is küldhetünk, mi is kezelhetünk: szignálozással “megszakításokat“ küldhetünk processzeknek. (A küldött szignál a processzeknek, az IT a CPU-nak szól.)
A szignálozás kapcsolódik a processz állapotokhoz, állapotátmenetekhez. Blokkolt egy processz egy eseményen: szignál billenti futásra kész állapotba (pl. bufferre vár, lehet, hogy az IT kezelő küldi a szignált). • Hogy értesül egy processz a szignálról? • Hogy kezeli le azt? • A vezérlés reakciója? Vadász
12
4
A szignál: jelzése egy eseménynek • Generálódik (mikor az esemény bekövetkezik), elküldik egy processznek. • A szignál diszpozíció fogalom (egy processz specifikálhatja, milyen rendszerakció menjen végbe a neki küldött szignálokra). Lehet: – alapértelmezési akció, – ignorálás (figyelmen kívül hagyás), – saját kezelő kezelje.
• Kikézbesített szignál fogalom (amikor az akció beindul. Generálódás és kikézbesítés között idő telhet el). • Függő szignál (pending signal) (generálódott, de még nem kézbesült ki. Külön érdekes a “blokkolt“ függő szignál!)
Vadász
13
Szignálozás SVID Unixban • A kernel a szignál kézbesítéséhez • A PCB egy mezejét beállítja. • A processz a kernel módból való visszatéréskor ellenőrzi a mezőket: lekezel, ha van mit. • A szignálkezelő alapértelmezésben: – Legtöbbször terminálja a processzt, néha core dump-ot ad. – Adhat hibajelzést a stderr-en, és utána terminál. – Hatásosan lekezeli a szignált és folytatódhat a futás.
• Bizonyos szignálok kezelését a felhasználó programozó átveheti. • Bizonyos szignálokat a programozó küldhet. Vadász
14
A felhasználó szignálkezelési lehetőségei Kérheti, hogy ignorálódjon (ekkor is kézbesül!) Kérheti, fusson saját kezelő függvény Kérheti, álljon vissza az alapértelmezés Postázhat bizonyos szignálokat (más processzeknek, de saját magának is) • A lekezelhető és küldhető szignálkészlet majdnem egybeesik • A szignálozást használhatja: szinkronizációra, kommunikációra. • • • •
Vadász
15
5
Szignálozással kapcsolatos API1 • Nézd a /usr/include/sys/signal.h header fájlt! Ebben: • Makrók, system call prototype-ok. # define SIGHUP 1 # define SIGINT 2 ... # define SIGALRM 14 # define SIG_IGN (void(*)()) 0 # define SIG_DFL (void(*)()) 1 stb. Vadász
16
Linux man 7 signal részlet • Signal Value Action Comment • ------------------------------------------------------------------------• SIGHUP 1 Term Hangup detected on controlling terminal or death of controlling process • SIGINT 2 Term Interrupt from keyboard • SIGQUIT 3 Core Quit from keyboard • SIGILL 4 Core Illegal Instruction • SIGABRT 6 Core Abort signal from abort(3) • SIGFPE 8 Core Floating point exception • SIGKILL 9 Term Kill signal • SIGSEGV 11 Core Invalid memory reference • SIGPIPE 13 Term Broken pipe: write to pipe with no readers • SIGALRM 14 Term Timer signal from alarm(2) • SIGTERM 15 Term Termination signal • SIGUSR1 30,10,16 Term User-defined signal 1 • SIGUSR2 31,12,17 Term User-defined signal 2 • SIGCHLD 20,17,18 Ign Child stopped or terminated • SIGCONT 19,18,25 Continue if stopped • SIGSTOP 17,19,23 Stop Stop process • SIGTSTP 18,20,24 Stop Stop typed at tty • SIGTTIN 21,21,26 Stop tty input for background process • SIGTTOU 22,22,27 Stop tty outputVadász for background process
17
Szignálozással kapcsolatos API2 • A signal() rendszerhívás [POSIX: sigaction()] void (*signal( )) ( ); A signal egy függvény, ami egy függvényre mutató pointerrel tér vissza. Ennek visszatérése pedig void.
• A szignál diszpozíció precízebben : void (*signal(int sig, void (*func)(int,..)))(int,..); A sig szignált a func függvény kezelje le. Siker esetén az előző lekezelő függvény címével, hiba esetén SIG_ERR értékkel tér vissza. Mind a func-nak, mind a visszatérési függvénynek lehetnek int argumentumai.
Fontos! Saját kezelőre diszponált szignál bekövetkezése (és kezelése) után sok rendszerben visszaáll az alapértelmezett diszpozíció!
Vadász
18
6
Szignálozással kapcsolatos API3 • A sigaction( ) rendszerhívás is dispozíció! • POSIX stílusú. int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact);
• Ahol a struct sigaction-nak van void (*sa_handler) (int); tagja. Ez a tag veheti fel az új és a régi kezelő címét.
Vadász
19
Szignálozással kapcsolatos API4 • A kill() rendszerhívás [POSIX: sigsend()] int kill(pid_t pid, int sig); Küldjön sig szignált a pid processznek. Siker esetén 0-val, sikertelenség esetén -1-gyel tér vissza.
• Hasznos még a raise(), a pause(), az alarm(), a sigprocmask(), a sigsuspend(), a sigsetjmp() és a siglongjmp() rendszerhívás is.
Vadász
20
Esettanulmányok, gyakorlatok • Nézzék az www.iit.uni-miskolc.hu/iitweb/opencms/users/DVadasz helyen
…/signals/alarmra-var1.c és …/signals/alarmra-var2.c példaprogramokat! • Nézzék az …/signals/alarm-ado1.c és …/signals/alarm-ado2.c példaprogramokat!
Vadász
21
7
#include <signal.h> void handler(int); /* one handler for both signals */ main(void) { if(signal(SIGUSR1,handler)==SIG_ERR) exit(0); if(signal(SIGUSR2,handler)==SIG_ERR) exit(1); for ( ; ; ) pause(); } void handler(int signo) { /* arg is signal no */ if (signo==SIGUSR1) printf("received SIGUSR1\n"); else if (signo==SIGUSR2) printf("received SIGUSR2\n"); else exit(2); return; 1 kezelő 2 }
szignálhoz
Vadász
22
Tanulmányozandó még ... • A sigprocmask()-hoz: létezik globális szignál maszk, ez definiálja, mely szignálok “blokkoltak“. • A sigsetjmp() és siglongjmp() érdekességek: int sigsetjmp(sigjmp_buf env[, int savemask]); void siglongjmp(sigjmp_buf env[, int val]); – A sigsetjmp lementi a C-stack-et és a regisztereket az env-be. Kétszer tér vissza! Először 0-val (direkt hívásakor), másodszor - a siglongjmp hívásával történő “visszavétel“ miatt a val értékkel (ha az 0, akkor 1gyel) – A siglongjmp() visszaveszi a regisztereket, a stack-et, és a val értékkel tér vissza (amit nem 0-ra állítunk).
Vadász
23
Példa #include <setjmp.h> jmp_buf env; int i = 0; main ( ) { if (setjmp(env) != 0) { (void) printf("2nd from setjmp: i=%d\n", i); exit(0); } (void) printf("1st from setjmp: i=%d\n", i); i = 1; g( ); /*NOTREACHED*/ } g( ) { longjmp(env, 1); /*NOTREACHED*/ } Vadász
24
8
A példa eredménye The program's output is: 1st from setjmp:i=0 2nd from setjmp:i=1
Vadász
25
További esetek .. • Stevens példája a …/signals/abort.c – Írtunk saját abort() függvényt. Azt nem lehet ignorálni, nem lehet kezelését átvenni, és nem lehet blokkolni sem. – Elemezzük.
Vadász
26
OPERÁCIÓS RENDSZEREK Eseménykezelés, szignálozás Vége
9