780 likes | 884 Views
Operációs rendszerek MINB240 2. előadás Szálak, IPC. 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.
E N D
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
Szál modell • 3 processzus, mindegyik egy szállal • 1 processzus, 3 szállal
Szál modell Nem csak processzus, hanem szál táblázat is van
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
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
Kép kérés processzussal Idő Kép kérés Kép kérés Processzus 1 server server Futás Várakozás
Kép kérés szállal Idő Kép kérés server Szál A (Processzus 1) Szál B (Processzus 1) Kép kérés server Futás Várakozás Várakozás, amí szál B végez
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
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
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
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ű
Processzusok kommunikációja • InterProcess Communication (IPC) • Milyen feladatokat lát el: • Egymás közötti információcsere • Erőforrások megosztás (ne keresztezzék egymást) • 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
Többszálas program, egy hibajelző Idő Szál 1 Szál 2 errno = -1 errno = -2 if(errno == -1) { …
Nyomtató démon Háttér katalógus Honnan vegyük a nyomtatandó file nevét? Hová tároljuk a nyomtatandó file nevét?
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
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.
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
Versenyhelyzet elkerülésének 4 feltétele • Ne legyen két processzus egyszerre a saját kritikus szekciójában (kölcsönös kizárás) • Semmilyen előfeltétel ne legyen a sebességekről vagy a CPU-k számáról • Egyetlen, a kritikus szekcióján kívül futó processzus sem blokkolhat más processzusokat (haladás) • Egyetlen processzusnak se kelljen örökké arra várni, hogy belépjen a kritikus szekciójába (korlátosság)
Kölcsönös kizárás kritikus szekcióval Idő A kritikus szekcióba lép A kilép a kritikus szekcióból Processzus A B megpróbál kritikus szekcióba lépni B kritikus szekcióba lép B kilép a kritikus szekcióból Processzus A B blokkolódik T4 T3 T2 T1
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
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
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(); }
Zárolásváltozó, a problémás futás Idő Processzus A Processzus B while(TRUE) { while(lock == 1); lock = 1; critical(); lock = 0; non_critical(); } while(TRUE) { while(lock == 1); lock = 1; critical(); lock = 0; non_critical(); }
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!!!
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 ...
Szigorú váltogatás Idő Processzus 0 Processzus 1 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(); ... Blokkolódik, amíg processzus 1 ismét végre nem hajt egy kritikus szekciót
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
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; }
Peterson megoldása Processzus 0 Processzus 1 while(TRUE) { enter_region(0); critical(); leave_region(0); non_critical(); } while(TRUE) { enter_region(1); critical(); leave_region(1); non_critical(); }
Peterson megoldása turn interested Processzus 0 Processzus 1 0 1 while(TRUE) { enter_region(0); critical(); critical(); leave_region(0); non_critical(); } while(TRUE) { enter_region(1); critical(); leave_region(1); non_critical(); } 0 0 1 0 0 1 1 1 0 1 1
Peterson megoldása turn interested Processzus 0 Processzus 1 0 1 while(TRUE) { enter_region(0); critical(); leave_region(0); non_critical(); } while(TRUE) { enter_region(1); critical(); leave_region(1); non_critical(); } 0 0 1 0 0 1 1 1 while(turn == process && interested[other] == TRUE) ; Ha majdnem egyszerre hajtják végre az enter_region részt akkor is működik!!!
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
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
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
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
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 gyártó X X X fogyasztó
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
Gyártó-fogyasztó probléma int count = 0; #define N 4 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); } } Együttes, ellenőrizetlen hozzáférés
Gyártó-fogyasztó probléma Processzus 0 Processzus 1 count 0 fogyaszto() { while(TRUE) { if(count == 0) sleep(); remove_item(); count--; if(count == N-1) wakeup(prod); } } gyarto(){ while(TRUE) { item = produce() if(count == N) sleep(); insert_item(); count++; if(count == 1) wakeup(con); } } Igaznak találja 1 Elalszik, örökre Elveszik, hiszen fogyasztó nem alszik Megtölti a buffert és elalszik
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
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
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ó
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 i Processzus j ... ... A down(count) up(count) B