270 likes | 376 Views
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. Hiba és eseménykezelés. Alapfogalmak.
E N D
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
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
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
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
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
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
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
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
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
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
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
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álfogalom (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
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
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
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
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 output for background process Vadász
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
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
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
Esettanulmányok, gyakorlatok • Nézzék az www.iit.uni-miskolc.hu/~vadasz/GEIAL202/Peldaprogramok/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
1 kezelő 2 szignálhoz #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; } Vadász
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 1-gyel) • A siglongjmp() visszaveszi a regisztereket, a stack-et, és a val értékkel tér vissza (amit nem 0-ra állítunk). Vadász
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
A példa eredménye The program's output is: 1st from setjmp:i=0 2nd from setjmp:i=1 Vadász
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
OPERÁCIÓS RENDSZEREK Eseménykezelés, szignálozás Vége