kategória | ||||||||||
|
||||||||||
|
||
Processzus:
Végrehajtás alatt lévő program (ennek egy absztrakciója)
Látszatpárhuzamosság:
A CPU gyors működésének köszönhetően több program is futhat egyszerre a számítógépen, de egy program csak ezredmásodpercekre kapja meg a CPU-t, ami kapcsolgat közöttük.
Valódi hardverpárhuzamosság:
Több processzor használja ugyanazt a memóriát.
A párhuzamosság kezelésére az op. rendszerek tervezői egy modellt fejlesztettek ki.
A processzus egy végrehajtás alatt lévő program. Minden processzusnak saját CPU-ja, virtuális CPU-ja van.
Valójában a processzor oda-vissza kapcsolgat a programok között, ezt multiprogramozásnak nevezzük.
Multiprogramozást kezelő számítógépmodell:
Egy processzus egy bizonyos fajta tevékenység, van programja, bemenő és kimenő adatai és állapota. Egy processzort bizonyos ütemezési algoritmussal megoszthatunk több processzus között, és ez az algoritmus eldönti, hogy mikor szakít meg egy processzust és vesz át egy másikat.
A processzus három állapotban lehet:
Futó (egy adott pillanatban éppen használja a CPU-t)
Futáskész (készen áll a futásra, ,ideiglenesen leállították, hogy egy másik processzus futhasson.)
Blokkolt (bizonyos külső eredmények bekövetkezéséig nem képes futni)
Ezen állapotok közötti átmenet:
A processzus input végett blokkolt.
Az ütemező másik processzusra vált.
Az ütemező erre a processzusra vált.
A bemenet elérhető.
A processzus ráébredt, hogy nem tudja folytatni.
Op. rendszer lehetséges teendői:
Egyes rendszerek a BLOCK rendszerhívást hajtják végre
Mások a processzus pájpból olvas és ha nincs elérhető bemenet, akkor automatikusan blokkolódik.
A 2. és 3. átmenetet a processzusütemező váltja ki, anélkül, hogy erről a processzus tudomást szerezne.
Arra, hogy a processzusütemező logon működjön, sok algoritmust találtak ki.
Szem előtt tartandó követelmény:
A rendszer hatékonysága.
Processzusok pártatlan kezelése.
A 4. átmenet esetén, ha nincs futó processzus, akkor azonnal futni kezd, míg ellenkező esetben a processzus vár az ütemezőre.
Az ütemező nemcsak processzus ütemezéssel foglalkozik, hanem megszakításkezeléssel és a processzusok közötti kommunikációval is.
A processzustáblázat tartalmazza a processzusokkal kapcsolatos adatokat:
Utasításszámlálója
Veremmutatója
Lefoglalt memória
Megnyitott fájljainak állapota
Ütemezési információ
Minden olyan információt a processzorról, amelyek ahhoz kellenek, hogy a processzus úgy indulhasson újra, mintha soha nem állítottuk volna le.
Minden B/K osztály (hajlékonylemez-egységek, merevlemez egységek) kapcsolatban van egy megszakításvektorral. Ez a megszakítást kiszolgáló eljárás címét tartalmazza.
Ha egy B/K eszköz megszakítást kér, akkor a megszakításhardver az utasításszámlálót és egy vagy több regisztert a verembe helyez, ezután a megszakítás kezelése szoftver feladata.
Megszakítás kiszolgáló eljárás:
Processzustáblába helyezi az összes regiszter tartalmát, majd a veremmutatót átállítja egy másik veremre és kiveszi a megszakítás által lerakott információkat. Ha nincs ennél nagyobb prioritású processzus, akkor ez fog futni.
A hardver verembe teszi az utasításszámlálót, regisztereket.
A hardver a megszakításvektorból betölti az új utasításszámlálót.
Az assembly nyelvű eljárás elmenti a regisztereket.
Az assembly nyelvű eljárás beállítja az új vermet.
A "C" megszakításkezelő fut.
Az ütemező bejelöli a várakozó folyamatra, hogy futáskész.
Az ütemező eldönti, hogy melyik legyen a következő futtatandó processzus.
A "C" eljárás visszatér az assembly kódba.
Az assembly nyelvű eljárás elindítja az új aktuális processzust.
Az op. rendszerek támogatják a processzuson belüli szálakat. Ezeket vezérlési szálaknak, vagy könnyűsúlyú processzusoknak nevezzük.
A szálak kezelése hasonlóan történik, mint a processzusok kezelése.
Néhány op. rendszer azonban tudomást sem vesz a szálakról.
A szálak közötti kapcsolgatás felhasználó szinten sokkal gyorsabb, mint rendszerhívással.
(a szálak kezelését felhasználói szinten kell végezni)
Ha egy szál blokkolódik felhasználói szintű szálkezelésnél, akkor az egész processzus blokkolódik.
(érvényes a szál op. rendszer szintű kezelésére)
Ha a szál fogalmát nem ismeri az op. rendszer és egy új verziónál bevezetésre kerül, akkor alapjaiban kell átírni az op. rendszert.
Olyankor, ha pl. az egyik processzus adatait át kell adni egy másiknak.
A processzus kommunikáció (InterProcess Communication) IPC
Versenyhelyzet:
Ha kettő vagy több processzus olvas vagy ír megosztott adatokat, és a végeredmény attól függ, hogy ki és mikor fut.
Pl.: Nyomtatási versenyhelyzet
Az A pakolni akar a háttértárba, de mikor kiolvassa az IN értéket, mielőtt pakolna bele, az időzítő B-nek adja a vezérlést, aki bepakol, és legközelebb A is a 7-esbe pakol, majd növeli az IN értékét.
Kritikus terület szekció:
A programnak az a része, amelyben a megosztott memóriát használja.
Ne legyen két processzus egyszerre a saját kritikus szekciójában.
Semmilyen feltétel ne legyen a sebességekről, vagy a CPU-k számáról.
Ne legyen olyan processzus, amely a kritikus szekcióján kívül futva blokkolhat más processzusokat.
Egy processzusnak se kelljen örökké arra várni, hogy belépjen a kritikus szekciójába
Kölcsönös kizárás elve:
Ha egy processzus használ megosztott változót vagy fájlt, a többi processzus tartózkodjon ettől.
Ha egy processzus belép a saját kritikus szekciójába az összes megszakítást letiltja, és újraengedélyezné, mihelyt kilépne belőle. (óramegszakítás sem fordul elő).
Hátránya: Felhasználói processzusnak olyan hatalmat ad, amivel ki tudja kapcsolni a megszakításokat.
Az op. rendszeren belüli megszakítástiltás hasznos lehet.
Megosztott zárolásváltozón keresztül ha értéke 0, akkor 1-re állítja, majd belép a kritikus szekcióba.
Hátránya: Ha egy processzus kiolvassa az értéket ami 0, majd más processzushoz kerül a vezérlés, amely kiolvassa a 0-át miután belép! Visszakerül a vezérlés az előzőhöz aki állítja az értéket és belép! 1-nek ellenkezőre.
A TURN változóban tárolják a következő szekcióba léphető processzust.
A processzusok várnak, amíg be nem léphetnek a saját kritikus szekciójukba.
Op. rendszer: 1. proc:
While(TRUE) }
Probléma akkor van, ha az egyik processzus lényegesen hosszabb a másiknál, amely ilyenkor sokat várakozik.
Ez ellentmond a 3. feltételnek, miszerint az egyik processzus blokkol egy olyan processzust, amely nem a kritikus szekciójában van.
1981-ben Peterson talált megoldást a kölcsönös kizárás megvalósítására.
Mielőtt megosztott változókat használna a processzus, meghív egy Enter_region függvényt, átadva a saját processzusának a számát.
Ha kell várakozik a biztos belépésig.
Kilépéskor meghívja a Leave_region függvényt.
Int turn; //ki következik
Int interested[i]; //minden érték 0 (FALSE)
Void enter_region (int process) //0 vagy 1 a processzus sorszáma
Void leave_region (int process)
A 0. processzus meghívja az enter_region-t
Process=0
Other=1
Interested[0]=TRUE
Turn=0
Ha az 1. nem érdekelt azonnal visszatér.
Egyébként várakozik, amíg interested[1]=FALSE nem lesz.
Ha az 1. most meghívja az enter_region-t, akkor vár míg az interested[0] FALSE-ra nem vált. Ez akkor következik be, ha a 0. processzus meghívja a leave_region-t.
Turn globális változó!
Ha mindkét processzus egyszerre hívja meg az enter_region-t, akkor csak az utolsó írás számít, mert az globális.
Ha az 1. ír be utoljára, akkor turn=1 lesz.
A while ciklushoz érve mindkettő vizsgál.
A 0. nem hajt végre ciklusmagot így belép a kritikus szekcióba.
Az 1. ismételget, nem lép be a szekciójába.
Hardversegítséget igényel. Sok processzor ismeri a TSL utasítást.
Beolvassa a memóriaszó tartalmát egy regiszterbe, és ezután egy (a szó beolvasása és tárolása nem választható szét) nemnulla értéket ír erre a memóriacímre.
A memória elérése az utasítás végrehajtása során minden CPU számára tilos.
A LOCK változót, ha az 0, minden processzus beállíthatja 1-re a TSL utasítással.
Enter_region;
Tsl register,lock //átmásolja a lock-ot a regiszterbe és 1-re állítja
Cmp regiszter,#0 //a lock 0 volt?
Jne enter_region #0 //ha nem volt 0, akkor be van állítva így ciklus
Ret //vissza és belépünk a kritikus szekcióba
Leave_region;
Move lock,#0 //lock legyen 0
Ret //visszatérés
Fordított prioritás probléma:
Mind a Peterson, mind a TSL megoldás tevékeny várakozást igényel a processzusok részéről.
Legyen H magas, L alacsony prioritású folyamat. Tegyük fel, hogy az ütemezés olyan, hogy ha H futáskész állapotban van, akkor futni is fog.
Ha L a kritikus tartományába kerül, és mielőtt kilépne onnan a H futáskész állapotba kerül, és aktív várakozásba kezd.
Mivel L-re soha nem fog sor kerülni, a H sem fog belépni a kritikus szekciójába. (Végtelen ciklus).
A blokkolás miatt az előző megoldások pazarolják a processzusidőt.
Új megoldások elve, hogy a processzusok SLEEP és WAKEUP rendszerhívásokkal altatják és ébresztik a rájuk váró processzusokat.
Gyártó-fogyasztó probléma:
Két processzus osztozik egy közös tárterületen.
Egyikük a gyártó, adatokat helyez el benne, a másik a fogyasztó, adatokat vesz ki onnan.
(A probléma általánosítható n gyártóra, és m fogyasztóra is.)
Nehézség a gyártó adatot pakolna, de már tele van a tárolóterület.
A megoldás, hogy a gyártó elmegy aludni, és felébresztik, ha kell.
Másik nehézség, amikor a fogyasztó venne a tárból, de nincs adat.
Ez egyszerűnek látszik, de ugyanolyan versenyhelyzeteket szül, mint a háttérkatalógusos nyomtatási probléma.
#define N 100 //A tároló rekeszeinek a száma
int count=0; //az elemek száma a tárolóban
Void producer (void) //gyártó
Void consumer (void)
While (TRUE){
If (count = = 0) sleep(); //üres tárolónál aludni megyünk
Remove_item(); //elem kivétele a tárolóból
Count = count-1; //elemek számának csökkentése
If (count = = N-1) wakeup (producer); //termelő ébresztése
Consume_item(); //felhasználjuk az elemet
Versenyhelyzetek itt (count globális, közös tárban van)
A tároló üres és a fogyasztó count-ot olvassa, ami 0, az ütemező elindítja a gyártót, aki berak egy elemet és növeli a count-ot. Mivel a count=1, ezért a gyártó hívja a wakeup-ébresztőt. Ha a fogyasztó ismét fut a count értékét 0-nak találja és elmegy aludni.
A gyártó telerakja a tárat és elmegy aludni.
Mindketten örökre aludni fognak.
A probléma az ébresztőjel elvesztése miatt történik.
Egy ébresztőt váró bit bevezetésével megoldható.
Ha olyan processzusnak küldünk ébresztőt, amelyik még ébren van, akkor ez a bit beállítódik. Később amikor aludni menne, és az ébresztőt váró bit be van kapcsolva kikapcsolja, és nem megy el aludni. Ez azonban nem szolgáltat teljes megoldást.
:
2120