1 Operációs rendszerek MINB előadás Szálak, IPC
2 Processzusok, szálak Egy processzus –Saját címtartomány –Egyetlen vezérlési szál Hasznos lehet több kvázi párhuzamos vezérlési szál használata egy címtartományban –Mintha különálló processzus lenne Szál (thread) vagy könnyű súlyú processzus
3 Szál modell (a)3 processzus, mindegyik egy szállal (b)1 processzus, 3 szállal
4 Szál modell Processzus elemeiSzál elemei CímtartományUtasításszámláló Globális változókRegiszterek Megnyitott fájlokVerem GyermekprocesszusokÁllapot Függőben lévő ébresztők Szignálok és szignálkezelők Elszámolási információk Nem csak processzus, hanem szál táblázat is van
5 Miért használunk szálakat? Hasonlóak a processzusokhoz, de... Kevesebb idő kell –a létrehozáshoz –a lezáráshoz –a szálak közötti váltáshoz A szálak egy memóriaterületen belül vannak így könnyen kommunikálhatnak a kernel hívása nélkül
6 Szövegszerkesztő
7 Többszálas Web böngésző Sok weblap tartalmaz több kis képet A böngészőnek minden képért külön kapcsolatot kell kiépítenie a lapot tároló számítógéppel A kapcsolatok felépítése és bontása sok idő A böngésző több szál használatával több képet kérhet le egyszerre
8 Kép kérés processzussal Processzus 1 Kép kérés Kép kérés server Futás Várakozás Idő
9 Kép kérés szállal Szál A (Processzus 1) Kép kérés server Futás Várakozás Idő Szál B (Processzus 1) Várakozás, amí szál B végez Kép kérés
10 Többszálas Web szerver
11 Felhasználói szintű szálak A kernel semmit nem tud a szálakról –Csak a processzusokat látja Szál kezelés egy könyvtárban van implementálva
12 Felhasználói szintű szálak, előnyök Szálak közötti kapcsolás gyorsabb –Nincs szükség kernel csapdára, rendszerhívásra Bármelyik operációs rendszer alatt implementálható Nagy számú szál hozható létre alkalmazásonként
13 Felhasználói szintű szálak, hátrányok A szálnak önként kell feladnia a futását –Nincs óra megszakítás a szálhoz –Együttműködő többszálas programozás Nem használja ki ha több CPU van a gépben Ha egy szál blokkolt, akkor az egész processzus blokkolt, hiszen a kernel semmit nem tud a szálakról
14 Kernel szintű szálak
15 Kernel szintű szálak Előnyök –Parallel működés Blokkolt I/O és számítás átlapolható Ki tud használni több processzort Hátrányok –Szál létrehozás és lezárás esetén szükség van a kernelbe lépésre (rendszerhívásra) –„Drágább” mint a felhasználói szintű
16 Hibrid szálak
17 Processzusok kommunikációja
18 Processzusok kommunikációja InterProcess Communication (IPC) Milyen feladatokat lát el: 1.Egymás közötti információcsere 2.Erőforrások megosztás (ne keresztezzék egymást) 3.Szinkronizáció (megfelelő sorrend kialakítása) Szálaknál –1. nem probléma (közös címtartomány) –2. és 3. ugyanúgy érvényes
19 Többszálas program, egy hibajelző Szál 1 Szál 2 errno = -1 errno = -2 if(errno == -1) { … Idő
20 Nyomtató démon Honnan vegyük a nyomtatandó file nevét? Hová tároljuk a nyomtatandó file nevét? Háttér katalógus
21 Versenyhelyzet Ha kettő vagy több processzus olvas vagy ír megosztott adatokat és a végeredmény attól függ ki és mikor fut Problémás lehet megtalálni a versenyhelyzetet –Legtöbb teszt jó, csak néha kapunk hibát
22 Versenyhelyzet Megoldás: –Megelőzés –Kölcsönös kizárás: egy módszer, amely biztosítja hogy ha egy processzus használ valamely megosztott változót, fájlt, akkor a többi processzus „tartózkodjon” ettől a tevékenységtől.
23 Kritikus terület, szekció Egy processzus ideje jelentős részét számítással tölti Néha a megosztott változókhoz, fájlokhoz kell hozzáférni Azt a részt mely megosztott részekhez fér hozzá kritikus területnek nevezzük Az kellene hogy két processzus azonos időben ne legyen kritikus szekcióban (kölcsönös kizárás) Koordinálatlan belépés a kritikus szekcióba verseny helyzethez vezet
24 Versenyhelyzet elkerülésének 4 feltétele 1.Ne legyen két processzus egyszerre a saját kritikus szekciójában (kölcsönös kizárás) 2.Semmilyen előfeltétel ne legyen a sebességekről vagy a CPU-k számáról 3.Egyetlen, a kritikus szekcióján kívül futó processzus sem blokkolhat más processzusokat (haladás) 4.Egyetlen processzusnak se kelljen örökké arra várni, hogy belépjen a kritikus szekciójába (korlátosság)
25 Kölcsönös kizárás kritikus szekcióval Processzus A T1T1 T2T2 T3T3 T4T4 A kritikus szekcióba lép A kilép a kritikus szekcióból B megpróbál kritikus szekcióba lépni B blokkolódik B kritikus szekcióba lép B kilép a kritikus szekcióból Idő
26 Megoldások és problémák
27 Kölcsönös kizárás tevékeny várakozással Tevékeny várakozás –A processzus folyamatosan ellenőrzi hogy beléphet-e a kritikus szekcióba –Semmi mást (hasznosat) nem tud csinálni a processzus Zárolásváltozó Szigorú váltogatás Peterson megoldása Hardware-es segítséggel
28 Zárolásváltozó Megosztott zárolásváltozó –Kezdetben értéke 0 –Mielőtt egy processzus belépne a kritikus szekcióba Ha a zárolásváltozó értéke 0, akkor 1-re állítja és belép a kritikus szekcióba Ha a zárolásváltozó értéke 1, akkor várakozik amíg 0 nem lesz
29 Zárolásváltozó, megoldás? while(TRUE) { while(lock == 1); lock = 1; critical(); lock = 0; non_critical(); } while(TRUE) { while(lock == 1); lock = 1; critical(); lock = 0; non_critical(); }
30 Zárolásváltozó, a problémás futás while(TRUE) { while(lock == 1); lock = 1; critical(); lock = 0; non_critical(); } while(TRUE) { while(lock == 1); lock = 1; critical(); lock = 0; non_critical(); } IdőProcesszus AProcesszus B
31 Zárolásváltozó, megoldás? Segít-e ha a megint ellenőrizzük a zárolásváltozót az írás előtt? ( lock = 1 ) NEM –A processzustól bármikor elvehetik a vezérlést!!!
32 Szigorú váltogatás while(TRUE) { while(turn != 0); critical(); turn = 1; non_critical(); } while(TRUE) { while(turn != 1); critical(); turn = 0; non_critical(); } Helyesen működik, de...
33 Szigorú váltogatás while(TRUE) { while(turn != 0); critical(); turn = 1; non_critical(); while(turn != 0); critical(); turn = 1; while(turn != 0); critical(); turn = 1; while(TRUE) { while(turn != 1); critical(); turn = 0; non_critical();... Processzus 0 Processzus 1 Blokkolódik, amíg processzus 1 ismét végre nem hajt egy kritikus szekciót Idő
34 Szigorú váltogatás 0. processzust blokkolta egy nem kritikus szekcióban levő processzus Sérti a 3. feltételt Akkor jó, ha a két processzus szigorúan váltogatja egymást
35 Peterson megoldása #define IGEN 1 #define NEM 0 #define N 2 int turn; int interested[N]; void enter_region(int process) { int other; other = 1 - process; interested[process] = IGEN; turn = process; while(turn == process && interested[other] == TRUE) ; } void leave_region(int process) { interested[process] = NEM; }
36 Peterson megoldása while(TRUE) { enter_region(0); critical(); leave_region(0); non_critical(); } while(TRUE) { enter_region(1); critical(); leave_region(1); non_critical(); } Processzus 0 Processzus 1
37 Peterson megoldása while(TRUE) { enter_region(0); critical(); leave_region(0); non_critical(); } while(TRUE) { enter_region(1); critical(); leave_region(1); non_critical(); } Processzus 0 Processzus 1 interested turn
38 Peterson megoldása while(TRUE) { enter_region(0); critical(); leave_region(0); non_critical(); } while(TRUE) { enter_region(1); critical(); leave_region(1); non_critical(); } Processzus 0 Processzus 1 interested turn while(turn == process && interested[other] == TRUE) ; Ha majdnem egyszerre hajtják végre az enter_region részt akkor is működik!!!
39 Hardware-es segítséggel, megszakítások Amikor belép a kritikus szekcióba letítja az összes megszakítást. Amikor kilép engedélyezi. Ilyenkor az órajel is tiltva van, nincs processzus átütemezés Probléma –Felhasználói processzus kezébe adjuk a megszakításokat (nem szerencsés) Mi van ha egy processzus soha nem kapcsolja vissza –Több CPU esetén a tiltás csak egy CPU-ra vonatkozik, így még mindig fennállhat a versenyhelyzet
40 Hardware-es utasítással Zárolásváltozók helyes implementálása Test and Set Lock utasítás: TSL RX,LOCK –Beolvassa a LOCK memóriaszó tartalmát az RX regiszterbe –Egy nem nulla értéket ír a LOCK memóriába Garantáltan nem szétválasztható, nem megszakítható műveletek –Atomi művelet –Az utasítást végrehajtva a CPU zárolja a memória sínt minden más CPU elől
41 Eddigiek összefoglalása Eddigi módszerek tevékeny várakozást használtak és van két problémájuk: –Aktívan használják a CPU-t, még a várakozás alatt is –Fordított prioritás probléma Legyen két processzus, H és L –H processzusnak magas a prioritása –L processzusnak alacsony a prioritása –Amikor H futáskész, mindenképp fut L belép a kritikus szekcióba H futáskész lesz és belépne a kritikus szekcióba –Örökké várni fog, mert L soha nem futhat
42 Alvás-ébredés Az ötlet: –Amikor a processzus egy eseményre vár, meghívja a sleep (altatás) függvényt és blokkolódik –Amikor az esemény bekövetkezik, az esemény generáló processzus (egy másik processzus), felébreszti ( wake-up ), futásra készre állítja a blokkolt processzust. Gyártó-fogyasztó probléma –Korlátos tároló problémának is nevezik
43 Gyártó-fogyasztó probléma A gyártó adatokat generál és egy bufferben tárolja A fogyasztó adatokat vesz ki a bufferből és felhasználja A két processzus egy közös, korlátos méretű tárolón osztozik XXX fogyasztó gyártó
44 Gyártó-fogyasztó probléma, kérdések Gyártó –Amikor a buffer megtelik, elalszik –Felébresztik, amikor a fogyasztó kivett adatokat Fogyasztó –Amikor a buffer üres, elalszik –Felébresztik, amikor a gyártó betett adatokat Versenyhelyzet alakulhat ki
45 Gyártó-fogyasztó probléma gyarto() { while(TRUE) { item = produce() if(count == N) sleep(); insert_item(); count++; if(count == 1) wakeup(con); } fogyaszto() { while(TRUE) { if(count == 0) sleep(); remove_item(); count--; if(count == N-1) wakeup(prod); } int count = 0; #define N 4 Együttes, ellenőrizetlen hozzáférés
46 Gyártó-fogyasztó probléma fogyaszto() { while(TRUE) { if(count == 0) sleep(); remove_item(); count--; if(count == N-1) wakeup(prod); } count Processzus 0 Processzus 1 0 gyarto() { while(TRUE) { item = produce() if(count == N) sleep(); insert_item(); count++; if(count == 1) wakeup(con); } 1 Elveszik, hiszen fogyasztó nem alszik Igaznak találja Elalszik, örökre Megtölti a buffert és elalszik
47 Szemaforok E.W. Dijkstra, 1965-ben javasolta Egész változókban számoljuk az ébresztések számát Az új változó típust szemafornak nevezte el (semaphor) Két művelet: –Down –Up Általánosabb mint, sleep-wakeup
48 down-up down –Megvizsgálja hogy a szemafor értéke nagyobb-e mint nulla? Ha igen, akkor csökkenti az értéket és folytatja Ha nulla, akkor a processzust elaltatja mielőtt befejeződne up –A szemafor értékét növeli –Ha egy vagy több processzus aludna ezen a szemaforon akkor egyet kiválaszt és megengedi hogy a down befejeződjön
49 Szemaforok Atomi, elemi műveletek (nem szedhetők szét) –Csak néhány utasítás Egy CPU esetén megszakítások használhatók Több CPU esetén a TSL utasítás használható
50 Szemaforok Szemaforok mint szinkronizációs eszközök Először A majd B részlet fusson le Szemafor: count = 0 Kód: Processzus iProcesszus j... Adown(count) up(count)B
51 Mutex Mutex = Mutual Exclusion (Kölcsönös kizárás) semaphor mutex; mutex = 1; /* inicializálás */ down(mutex); /* belépés a kritikus szekcióba */ kritikus szekció up(mutex); /* kilépés a kritikus szekcióból */
52 Gyártó-fogyasztó probléma szemaforral 3 szemafor –full (0): tele rekeszek száma –empty (N): üres rekeszek száma –mutex (1): biztosítja, hogy egyszerre csak az egyik processzus érje el a tárolót
53 Gyártó-fogyasztó probléma szemaforral gyarto() { while(TRUE) { item = produce() down(&empty); down(&mutex); insert_item(); up(&mutex); up(&full); } fogyaszto() { while(TRUE) { down(&full); down(&mutex); remove_item(); up(&mutex); up(&empty); }
54 Szemaforok összefoglalva Szemaforokkal többféle probléma megoldható Ugyanakkor könnyű hibázni –Azonos számú down és up kell –Megfelelő sorrendben kell őket kiadni
55 Monitorok Programozás könnyítésére Hoare (1974) javasolta –Magas szintű szinkronizációs primitív –A programozási nyelv része Ötlet –Függvények és változók egy speciális modulba vannak csoportosítva –Egyszerre csak egy processzus/szál hajthatja végre a monitoron belüli részt Fordító (compiler) biztosítja a kölcsönös kizárást
56 Egyszerű példa monitor szamlalo { int count; inc() { count = count + 1; } dec() { count = count - 1; } Kölcsönös kizárást biztosít Nincs versenyhelyzet a count változón
57 Eddigiek összefoglalás Szemaforok túl alacsony szintűek A monitorok csak néhány programozási nyelvben használhatók Mindkét esetben a processzusok elérik a közös memóriát Mi van ha több CPU - több memóriával rendelkezünk? (Nincs közös memóriaterület.)
58 Üzenetküldés Két primitív –send: küldés send(cél, üzenet); –receive: fogadás receive(forrás, &üzenet); Egyszerűek, akár könyvtári függvények is lehetnek –MPI: Message Passing Interface –PVM: Parallel Virtual Machine
59 Szinkronizálás A küldő és fogadó lehet blokkoló vagy nem blokkoló Blokkoló küldés, blokkoló fogadás –Mind a küldő, mind a fogadó blokkolódik amíg az üzenet meg nem érkezik teljesen –Ezt randevúnak hívják
60 Szinkronizálás Nem blokkoló küldés, blokkoló fogadás –A küldő folytatja működését –A fogadó blokkolódik amíg az üzenet meg nem érkezik Nem blokkoló küldés, nem blokkoló fogadás –Egyik processzus sem várakozik, blokkolt –A fogadó kaphat üzenetet vagy semmit
61 Üzenetek küldése Direkt címzés –Minden processzushoz hozzárendelünk egy egyedi címet Az üzenetet a processzusokhoz kell címezni Indirekt címzés –Levelesláda A címzés a levelesládának szól Több üzenetet is képes tárolni ideiglenesen Ha egy láda tele van a küldő felfüggesztődik A fogadó a levelesládából fogadja az üzeneteket Két processzus csak akkor kommunikálhat ha közös a levelesládájuk
62 Üzenetküldés, tervezési szempontok Olyan problémák amelyekkel eddig nem kellett foglalkozni –Üzenetek elveszhetnek a hálózaton Lehet nyugtázó üzenetet kérni Ha a küldő nem kapja meg a nyugtázó üzenetet, újra elküldi az üzenetet –Üzenet megjön, de a nyugta elvész Ismét megkapja az üzenetet. Mi legyen vele? Sorszámmal megoldható –Ugyanolyan sorszám esetén felismerhető, hogy már megérkezett
63 Üzenetküldés, tervezési szempontok Hitelesítés –Tényleg a fájl szerverrel kommunikálunk-e?
64 !!!!!!!!!! Példa: szálak Felhasználói szintű szálak –POSIX Pthreads –Win32 threads –Java threads Kernel szintű szálak –Windows XP/2000 –Solaris –Linux –Mac OS X
65 Több szálas modellek Sok-egy Egy-egy Sok-sok
66 Sok-egy Sok felhasználói szintű szál tartozik egy kernel szintű szálhoz Példák –Solaris Green Thread –GNU Portable Thread
67 Egy-egy Minden felhasználói szintű szálnak egy kernel szintű szál felel meg Például –Windows NT/2000/XP –Linux –Solaris 9 és később
68 Sok-sok Több felhasználói szál több kernel szálhoz tartozhat Például –Solaris 9 előtt –Windows NT/2000 a ThreadFiber csomaggal
69 Két szintű model Hasonló a sok-sok modelhez, de lehetőség van egy-egy megfeleltetésre is Például –IRIX –HP-UX –Tru64 Unix
70 Windows 2000 processzus
71 Windows 2000 szál
72 Windows 2000 szál állapotok
73 Solaris Felhasználói szintű szálak Kernel szintű szálak Könnyű processzusok (Lightweight processes)
74 Solaris
75 Unix vs. Solaris
76 Solaris
77 Linux