KURZUS: Számítógépes folyamatirányítás
MODUL: A dinamika
6.2. lecke: A szinkronizációs elemek és a monitor működése
Cél: A lecke célja, hogy a tananyag felhasználója | |||
| |||
Követelmények: Ön akkor sajátította el megfelelően a tananyagot, ha | |||
| |||
Időszükséglet: 2 óra | |||
Kulcsfogalmak: | |||
| |||
1. A szinkronizációs elemek | |||
Jegyezze meg a szinkronizációs elem fogalmát és típusait. | |||
A taskok működésük összehangolására, egymás futásának kölcsönös kizárására a monitor által biztosított un. szinkronizációs elemeket használhatják. Két ilyen elem van: a flag és a postaláda. | |||
A szinkronizációselemek (de a később tárgyalandó erőforrások is) névvel (számmal) azonosítható logikai elemek. A 'logikai elem' terminus azt jelenti, hogy fizikailag nem léteznek. Akármilyen kis darabokra szedünk szét egy számítógépet, nem fogjuk megtalálni őket. Létük az általuk kiváltott hatásban van, és ez a hatás nagyon is valóságos. A hatás úgy jön létre, hogy pontosan betartjuk a kezelésükre vonatkozó szabályokat, vagyis adott esetben nem tehetünk meg akármit, hanem csak úgy cselekedhetünk, hogy közben e fiktív objektumokra vonatkozó játékszabályok ne sérüljenek. | |||
1.1. A flag (szemafor) | |||
Jegyezze meg a flag fogalmát és használatát (példával); | |||
A flag egy névvel azonosítható kétállapotú logikai elem, amely lehet SET ("szabad") és RESET ("tilos") állapotban. Egy flag (például) egy esemény leképezésére alkalmas: ha az esemény bekövetkezett, a flag SET, ha még nem, akkor RESET állapotú. Az esemény tartalma a flag kezelése szempontjából teljesen érdektelen, azt csak a taskoknak kell ismerniük. | |||
A flaggel négy művelet végezhető, mindegyik művelet egy-egy monitorhívással realizálható: | |||
| |||
Minden monitorhívásnál paraméterként meg kell adni a flag számát. | |||
Egy flag közvetítésével mindig két task kerül kapcsolatba egymással. A taskok viszonya a flaghez aszimmetrikus: az egyik állítja, a másik vizsgálja, illetve várakozik a SET állapotra. Az RQSTF, RQCLF és az RQASK hívások nem vihetik WAIT állapotba a hívó taskot. Az RQWTF hívásnál a hívó várakozni kényszerül, ha a flag tilosra áll és csak akkor kerülhet újra aktív állapotba, ha a másik szabadra állítja a szemafort. Egy task lekérdezheti egy flag állapotát (RQASK). Ez nem okozhat várakozást, viszont tilos szemafor esetén a task nyilván nem csinálhatja azt a továbbiakban, amit szabad szemafor esetén csinálna. | |||
A flag használatára nézzünk egy egyszerű példát. Két task közösen használ egy memóriaterületet, az egyik (I) írja, a másik (O) olvassa. Amíg I be nem fejezte az írást, O nem olvashat, és fordítva. A kölcsönös kizárásra két flaget használnak: IE az írás engedélyező, OE az olvasás engedélyező flag. Az IE-t O állítja és I vizsgálja, az OE-t I állítja és O vizsgálja. I az írást csak akkor kezdheti meg, ha IE szabadra áll. Az írás megkezdése előtt OE-t tilosra, befejezésekor pedig szabadra kell állítania. O az olvasást csak akkor kezdheti, ha OE szabadra áll. Az olvasás megkezdése előtt IE-t tilosra, befejezésekor pedig szabadra kell állítania. A példa nagyon jól szemlélteti a flagek használatát, de maga a feladat más eszközzel sokkal elegánsabban megoldható. | |||
A monitor több (64, 128,...) flaget biztosít a taskok számára. A monitortáblákban minden flaghez egy bájt tartozik, amely a flag állapotát tartalmazza. (Az állapotinformáció tárolására egy bájt pazarlóan sok, viszont a szelektív bitkezelés igen hosszadalmas művelet és a monitor gyors működése még a hajdani, memóriaszűkös világban is sokkal fontosabb szempont volt, mint a memóriatakarékosság.) | |||
1.2. A postaláda (exchange) | |||
Jegyezze meg a postaláda és az üzenet fogalmát, használatát, fogalmazza meg a termelő és a fogyasztó közötti üzenetforgalom mechanizmusát; | |||
A postaláda egy névvel azonosítható kétállapotú logikai elem, amely lehet "üres" és "nem-üres" állapotban. A postaládába lehet üzenetet küldeni, vagy (ha nem üres) lehet belőle üzenetet venni. | |||
Az exchange kezelésére két monitorhívás szolgál: | |||
| |||
Mindkét hívásnál paraméterként meg kell adni a postaláda számát, ezen kívül az RQSEN-nél a küldendő üzenet kezdőcímét. Az RQWTE hívás, ha van üzenet, annak kezdőcímét adja vissza. | |||
Az RQSEN hívásnál a hívó task nem kerülhet WAIT állapotba, az RQWTE-nél - üres postaláda esetén - igen. A várakozó állapotból a task akkor szabadul, ha üzenet érkezik az exchangebe. | |||
Az üzeneteket, ahogy a postán a leveleket, borítékban kell küldeni. A borítéknak itt az elhasznált (feldolgozott) üzenet felel meg. Így a küldőnek először kell vennie egy elhasznált üzenetet, annak tartalmát felül kell írnia az új adatokkal (aktualizálni kell), és ezt kell érvényes új üzenetként elküldenie. A vevő, miután feldolgozta a kapott üzenetet, nem dobhatja el, hanem elhasznált üzenetként el kell küldenie egy erre a célra fenntartott postaládába. | |||
A vázolt üzenetforgalom két task között két postaláda közvetítésével szervezhető meg (1. ábra). | |||
| |||
A két task szerepe nem szimmetrikus. Az egyik a termelő (T), ő küldi a feldolgozandó üzeneteket, a másik a fogyasztó (F), ő dolgozza fel a kapott üzeneteket. Az egyik postaládában (X1) a feldolgozandó (érvényes), a másikban (X0) az elhasznált üzenetek gyülekeznek. A termelő X0-ból vesz és X1-be küld, a fogyasztó X1-ből vesz és X0-ba küld. | |||
A körforgásban résztvevő üzenetek száma állandó. Ezt a számot a fogyasztó szabja meg oly módon, hogy a rendszer indulásakor adott számú üres borítékot ("elhasznált" üzenetet) küld X0-ba. Később a borítékok száma már nem változhat, bármely időpontban az üzenetek egy része érvényes, más része elhasznált. Ha sok üzenet van forgalomban, a gyorsabb task megszaladhat a lassúbbhoz képest. Mivel azonban az üzenetek összes száma állandó, egy idő után észre fogja venni, hogy a megfelelő exchange-ből nem kap üzenetet, így küldeni sem tud, és le fog fékeződni. (Egyébként a gyorsabb task - lassúbb task szereposztás nem örök érvényű, azt számtalan változó körülmény befolyásolja és dinamikusan változhat.) A forgalomban lévő üzenetek számának növelése rugalmasabbá, csökkentése merevebbé teszi a két task kapcsolatát. Ha csak egy üzenet van forgalomban, akkor a kölcsönös kizárás esete valósul meg. | |||
Maga az üzenet egy adott hosszúságú memóriaterület, amely két részből, az üzenetfejből és az üzenettörzsből áll. Az üzenetfejet a monitor használja, a taskoknak szigorúan tilos megváltoztatni. Az üzenettörzs az üzenet tartalmi része, ennek értelmezése az érintett taskok belügye. | |||
A postaláda egy, az üzenetfejjel azonos méretű, egy cím tárolására alkalmas memóriaterület (pl. két bájt, vagy egy szó). A monitor az üzeneteket láncolt FIFO-ba rendezve csatolja a postaládához oly módon, hogy minden üzenetfej a következő üzenet pointere (2. ábra). | |||
| |||
Az utolsó üzenet fejében un. láncvég-jel van. A postaláda az első üzenetre mutat. Ha a postaláda üres, akkor ő tartalmazza a láncvég-jelet. Az üzenetlánc FIFO jellege biztosítja, hogy a vevő task a küldés sorrendjében kapja meg az üzeneteket. | |||
A láncolási mechanizmus a következőképpen működik: üzenetküldéskor a monitor a lánc utolsó üzenetének fejéből kiveszi a láncvég-jelet és a küldött üzenet címét helyezi bele, míg a láncvég-jel az újonnan becsatolt üzenet fejrészébe íródik.. Üzenetvételkor a postaládában lévő címet kapja meg a hívó, majd a postaládába a kicsatolt üzenet fejében lévő cím íródik. | |||
A monitor a taskok számára több (64, 128,...) postaládát biztosít. | |||
2. Az erőforrás | |||
Jegyezze meg az erőforrás fogalmát és használatát (példával), fogalmazza meg az erőforrás használatával kapcsolatos problematikus helyzeteket. | |||
Az erőforrás egy névvel azonosítható kétállapotú logikai elem, amely lehet "szabad", vagy "foglalt" állapotban. Ez eddig a két állapot elnevezésétől (ami egyébként lényegtelen) eltekintve azonos a flag és a postaláda kapcsán mondottakkal, és fogalmunk sincs, hogy mi az erőforrás. Ha a lényeget akarjuk megragadni, a következőt kell mondanunk. | |||
Az erőforrás olyan logikai elem, amely egyidejűleg csak egy task birtokában lehet, de amelyet ugyanakkor több task konkurens módon igényel. Ebből már látható, hogy az erőforrás olyan valami (bármi), amiből adott időben kevesebb van, mint amennyi kellene, ezért versenyezni kell érte. Az erőforrás tehát a rendszer szűk keresztmetszeteit leképező, illetve azok kezelését lehetővé tevő elem. Abban a pillanatban, amikor a valamiből annyi lesz, amennyi kell, a valami elveszíti erőforrás jellegét, mert minden igénylőnek meglesz a saját valamije és senki nem verseng már érte. (Egyébként a rendszer legfőbb erőforrása a processzoridő, de ezt a monitor saját hatáskörén belül osztja el.) | |||
Az erőforrást lehet igényelni (lefoglalni) és elengedni (visszaadni, felszabadítani). E műveletekre két monitorhívás van: | |||
| |||
Mindkét hívásnál paraméterként meg kell adni az erőforrás azonosítóját. | |||
Az RQRES híváskor, ha az erőforrás szabad, a hívó task megkapja (ezzel az erőforrás foglalttá válik), és futhat tovább. Ha az erőforrás nem szabad, a hívó WAIT állapotba kerül és a monitor bejegyzi az adott erőforrásra várakozók prioritás szerinti láncába. Ha az erőforrás felszabadul, akkor a rá váró tskok közül a legmagasabb prioritású kapja meg, a többinek pedig tovább kell várnia. Az RQRLS hívással a task visszaadja az általa birtokolt erőforrást. Ez a hívás nem viheti WAIT állapotba a taskot. | |||
Egy task csak általa birtokolt (megelőzőleg lefoglalt és megkapott) erőforrást engedhet el, vagyis nem lehet egy RQRLS hívással egy másik tasktól elvenni az erőforrást. | |||
A tasknak a már nem használt erőforrást azonnal fel kell szabadítania. | |||
Egy task egyszerre csak egy erőforrást foglalhat le, és amíg el nem engedte, másikat nem igényelhet. (Ezt a monitor nem ellenőrzi ugyan, de kötelező betartani.) Ellenkező esetben un. holtpont alakulhat ki és a szabályszegő task soha többé nem fog futni. Vizsgáljuk meg ezt részletesebben! Az A task fut, lefoglalja és megkapja az erőforrást. Fut tovább és előzetes elengedése nélkül kéri a erőforrást. Ám az foglalt, egy B task foglalja, így A WAIT állapotba kerül. Egyszer csak B-re kerül a sor, ő fut, és mielőtt -t elengedné, kéri -t. Ám foglalt az A által, így B is WAIT állapotba kerül. Most már mind a ketten várakoznak, és mivel sem -t, sem -t más nem szabadíthatja fel, örökre várakozni is fognak. Fokozza (ha még lehet) a bajt, hogy ez az ájulat tovább gyűrűzhet, mert bármely olyan task, amely a későbbiekben az említett két erőforrás valamelyikét igényli, szintén örökre várakozó állapotba zuhan. | |||
Néhány példa az erőforrás alkalmazására: | |||
| |||
Szokás az erőforrást is a szinkronizációs elemek közé sorolni. Mi azért választottuk külön, mert más a funkciója. A szinkronizációs elemek közvetítésével rendszerint két task lép egymással kapcsolatba, míg az erőforrás esetében egy task az összes konkurens partnerével úgy, hogy átmenetileg kizárja őket a működésből. | |||
A monitor több (64, 128, ...) erőforrást bocsát a taskok rendelkezésére. A monitortáblákban minden erőforráshoz egy állapotbájt (szabad/foglalt), egy, az aktuális birtokos task számát tartalmazó bájt, és az igénylők várakozási sora tartozik. | |||
3. Az I/O hívások | |||
Jegyezze meg az I/O-kezeléssel kapcsolatos monitorhívásokat; | |||
Az I/O kezelés a real-time monitorok legkevésbé általánosítható jellemzője. Több monitor a perifériakezelő programok (un. handlerek) bő választékát tartalmazza, míg másokhoz ezeket külön meg kell írni és megszakítás által aktivált task-ként, bizonyos előírások betartásával a monitor alá kell generálni. | |||
Ami többé-kevésbé általános, az a következő: A handlerek a perifériákat megszakításosan kezelik, a beérkező, illetve kiküldendő adatokat a monitor csatornánként input, illetve output FIFO-kba gyűjti. A taskok a perifériákat egyáltalán nem látják, sőt, a FIFO-khoz is csak monitorhívásokkal férhetnek hozzá. | |||
Két tipikus I/O-kezelő monitorhívás van: | |||
| |||
Mindkét monitorhívásnál meg kell adni a csatornaszámot. | |||
Az RQINP-nél a task várakozó állapotba kerül, ha az input FIFO üres, ha nem, megkapja a legrégibb adatot és futhat tovább. Az RQOUT-nál paraméterként meg kell adni a kiküldendő adatot. A hívás után a task várakozó állaotba kerül, ha a FIFO tele van, ha még van hely, az adat bekerül a sorba és a task futhat tovább. | |||
4. Egy megjegyzés a taskok türelméről | |||
A tárgyalt monitorhívások között van négy olyan (az RQWTF, az RQWTE, az RQINP és az RQOUT), amelyek hívásakor a hívó tasknak paraméterként meg kell adnia egy időtartamot is, mellyel a monitor tudomására hozza, hogy WAIT állapotba kerülése esetén legfeljebb mennyi ideig hajlandó várakozni. Ezt az időtartamot time-out-nak nevezik, magyarul úgy mondhatjuk: türelmi idő. A time-out lehet végtelen, valamilyen véges érték, vagy zérus. | |||
Ha a time-out végtelen, a task, amikor újra aktív állapotba kerül, biztos lehet abban, hogy a monitortól kért szolgáltatás rendben teljesült. Ha pl. üzenetre várt (RQWTE), továbbfutáskor biztos lehet abban, hogy megkapta az üzenetet. | |||
Ha a time-out nem végtelen, továbbfutáskor a tasknak tudnia kell, hogy most azért futhat, mert időközben teljesült a továbbfutás feltétele, vagy csak azért, mert a türelmi idő lejárt. A két különböző esetben ugyanis a task nyilvánvalóan nem folytathatja azonos módon a tevékenységét. A monitor ilyenkor visszaadott paraméterben közli a továbbfutás körülményeit, és a taskra van bízva, hogy mit tesz. | |||
5. A monitor működése | |||
Említettük, hogy a monitor két esetben fut: óra-interruptkor, illetve - a köztes időben - monitorhíváskor. Most, amikor megkíséreljük összegyűjteni a monitor konkrét tevékenységeit, a korábbiakra támaszkodva már igen egyszerű helyzetben vagyunk. | |||
A)Óra-interrupt: Az összes időtől függő tevékenység ekkor zajlik le. | |||
| |||
B)Monitorhívás: Időtől függő tevékenység nincs, az megtörtént az előző óra-interruptnál. | |||
| |||
A második tevékenységsor leírása nagyon általánosnak és felületesnek tűnik (pedig éppen olyan pontos, mint az első). Ez természetes is, mert nem mondtuk meg, hogy milyen konkrét monitorhívásról van szó. | |||
Nagyon javasoljuk az Olvasónak, hogy néhány konkrét hívás esetében alaposan gondolja át a működés részleteit, vagyis töltse meg konkrét tartalommal a fenti, nagyon általánosan megfogalmazott utalásokat! Ennek kapcsán azt is gondolja át, hogy egy olyan ártatlan monitorhívásnál, amely biztosan nem viheti WAIT állapotba a hívót, vajon biztosan ő fog-e tovább futni, vagy olyan eset is előfordulhat, hogy csak aktív marad, de mégsem ő fut! Vagy plasztikusabban fogalmazva: előfordulhat-e, hogy valakit kihúzunk a gödörből és az hálából nem lök ugyan bele a gödörbe, de elveszi tőlünk a biciklit és otthagy? | |||
Lépjen ki a tananyagból! Gondolja át a lecke tartalmát, rekonstruálja a szerkezetét! Vegyen elő egy lapot és írja le a lecke vázlatát! Ne sajnálja az erre fordított időt! Ha gondosan megcsinálja, már majdnem tudja is az anyagot. |
Önellenőrző kérdések | |||||||||||||
1. Mondja el a szinkronizációs elem fogalmát és sorolja fel típusait! | |||||||||||||
2. Mondja el a flag fogalmát, használatát, és sorolja fel a flaget kezelő monitorhívásokat! | |||||||||||||
3. Jelölje meg a helyes kijelentéseket!
![]() | |||||||||||||
4. Mondja el a postaláda és az üzenet fogalmát, használatát, és sorolja fel az üzenetforgalmat lebonyolító monitorhívásokat! | |||||||||||||
5. Jelölje meg a helyes állításokat!
![]() | |||||||||||||
6. Gondolja meg, mi történne, ha termelő az érvényes üzeneteket a lejárt (üres) üzenetek ládájába küldené! | |||||||||||||
7. Mondja el az erőforrás fogalmát, használatát, és az erőforráskezelő monitorhívásokat! | |||||||||||||
8. Jelölje meg a helyes állításokat!
![]() | |||||||||||||
9. Ismertesse az I/O kezelés monitorhívásait! | |||||||||||||
10. Mondja el a time-out fogalmát és a time-out-os monitorhívások speciális működését! | |||||||||||||
11. Sorolja fel a monitor tevékenységeit óra-interrupt, illetve monitorhívás esetén! |