Operációs rendszerek
 9635533144, 9789635533145 [PDF]

  • 0 0 0
  • Gefällt Ihnen dieses papier und der download? Sie können Ihre eigene PDF-Datei in wenigen Minuten kostenlos online veröffentlichen! Anmelden
Datei wird geladen, bitte warten...
Zitiervorschau

BAKOS TAMÁS - ZSADÁNYI PÁL

OPERÁCIÓS RENDSZEREK

Számítástechnika-alkalmazási Vállalat Budapest, 1989, 2001

Lektorálta: Kovács Ervin Supervised by Ervin Kovács

Copyright by Bakos Tamás - Zsadányi Pál, 1989 (első kiadás), 2001 (co memorial e-text)

ISBN 963 553 141 3

Kiadja a Számítástechnika-alkalmazási Vállalat Felelős kiadó: Havass Miklós vezérigazgató Felelős szerkesztő: Kardoss Zsuzsa Műszaki vezető: Kiss Ádám Műszaki szerkesztő: G. Müller Zsuzsa Olvasó szerkesztő: Gyömöre Mihályné, Lukács Erzsébet A (eredeti) rajzokat készítette: Dávidné Hujber Éva és Csermely Réka Megjelent: 17 (B/5) ív terjedelemben Készítette: FÜTI Nyomdaüzem, Azonossági szám: 89-149 Példányszám: 1500 Felelős vezető: Rédi Zoltánné Co memorial e-text supervised by Zsadányi Pál, 2000-2001

TARTALOMJEGYZÉK

OS!TV18.RTF,2001-04-23.ZSP; végleges állapot ELŐSZÓ.............................................................................................................................................1 1. BEVEZETÉS..............................................................................................................................3 1.1. Rendszerek és struktúrák........................................................................................................3 1.2. Számítógépes rendszerek.......................................................................................................7 1.3. Az operációs rendszer fogalma..............................................................................................9 1.4. Hardver alapfogalmak..........................................................................................................10 1.4.1. Processzorok........................................................................................................................10 1.4.2. Tárak....................................................................................................................................15 1.4.3. Háttértárak............................................................................................................................16 1.4.4. Egyéb perifériák...................................................................................................................17 1.5. Mintapéldák: hardverarchitektúrák......................................................................................18 1.5.1. IBM 360/370, ESZR-I/II/III sorozatok................................................................................18 1.5.2. PDP 11, MSZR I/II, VAX, MSZR III sorozatok..................................................................19 1.5.3. INTEL 8086/8088, 80286, 80386 mikroprocesszor család..................................................20 1.6. Gyakorlatok..........................................................................................................................22 2. AZ OPERÁCIÓS RENDSZEREK FUNKCIÓI.......................................................................23 2.1. Rendszeradminisztráció.......................................................................................................23 2.2. Programfejlesztési támogatás...............................................................................................24 2.2.1. A programozási munka részfeladatai..............................................................................25 2.2.2. Támogatások a problémaelemzéshez..............................................................................25 2.2.3. A programírás támogatása...............................................................................................25 2.2.4. Támogatás a programok belövéséhez..............................................................................28 2.2.5. A programintegrálás támogatása.....................................................................................30 2.2.6. A programfejlesztési támogatás fő funkcióinak összefoglalása......................................30 2.3. Alkalmazói támogatás..........................................................................................................30 2.3.1. Az operátori nyelvi rendszerek........................................................................................31 2.3.2. A munkavezérlő-nyelvi rendszerek.................................................................................31 2.3.3. A rendszerszolgáltatási funkciók.....................................................................................32 2.3.4. A segédprogram-készlet..................................................................................................32 2.3.5. Alkalmazói programcsomagok.......................................................................................32 2.4. Mintapéldák..........................................................................................................................32 2.4.1. Az IBM 360/370/30XX/43XX és az ESZR-I/II/III sorozat operációs rendszerei............................................................................................32 2.4.2. Az OS munkavezérlő nyelvének alapelemei...................................................................36 2.4.3. Az IBM PC operációs rendszerei....................................................................................41 2.4.4. Alapvető DOS parancsok................................................................................................44 2.5. Gyakorlatok..........................................................................................................................50

3. AZ OPERÁCIÓS RENDSZEREK OSZTÁLYOZÁSA...........................................................51 3.1. Osztályozási elvek................................................................................................................51 3.2. Egyfelhasználós rendszerek.................................................................................................54 3.3. A multiprogramozás alapelve...............................................................................................55 3.4. Multiprogramozott rendszerek.............................................................................................56 3.4.1. Spooling technika............................................................................................................56 3.4.2. Tárkezelési problémák.................................................................................................... 58 3.4.3. Központi egység elosztás................................................................................................ 60 3.4.4. A holtpontok problémája................................................................................................ 60 3.4.5. Védelmi kérdések............................................................................................................ 61 3.5. Kötegelt (batch) rendszerek................................................................................................61 3.6. Időosztásos rendszerek........................................................................................................62 3.7. Valós idejű rendszerek........................................................................................................ 63 3.8. Többprocesszoros rendszerek............................................................................................. 64 3.9. Hálózatok és elosztott rendszerek..................................................................................... 65 3.10. Mintapéldák.......................................................................................................................... 67 3.11. Gyakorlatok.......................................................................................................................... 70 4. MŰVELETI FÁZISOK............................................................................................................71 4.1. A feladat egysége: a munka..................................................................................................71 4.2. Munkafogadási fázis............................................................................................................72 4.3. Munkakiválasztás.................................................................................................................73 4.4. Programfordítás....................................................................................................................73 4.5. Programszerkesztés..............................................................................................................74 4.6. Programaktiválás és erőforrás hozzárendelés......................................................................76 4.7. Programbetöltés....................................................................................................................77 4.8. Programvégrehajtás..............................................................................................................77 4.9. Záró fázis..............................................................................................................................78 4.10. Rendszerfolyamatok.............................................................................................................78 4.11. Mintapéldák..........................................................................................................................78 4.12. Gyakorlatok..........................................................................................................................80 5. RENDSZERSZOLGÁLTATÁSOK..........................................................................................81 5.1. Alapkoncepció......................................................................................................................81 5.2. Vezérlőáram-kezelés............................................................................................................81 5.3. Tárkijelölés és programbetöltés...........................................................................................82 5.4. Szerkesztőmenet...................................................................................................................83 5.5. Magas szintű ütemezés.........................................................................................................83 5.6. Működésoptimalizálás..........................................................................................................84 5.7. Alrendszerek kezelése..........................................................................................................85 5.8. Mintapéldák..........................................................................................................................88 5.8.1 Az IBM OS TSO alrendszere..........................................................................................88 5.8.2 Nyilvános adatbázis szolgáltatások.................................................................................90 5.9. Gyakorlatok..........................................................................................................................92

6. BELSŐ ARCHITEKTÚRA......................................................................................................93 6.1. Rendszermag (kernel)..........................................................................................................93 6.1.1. A rendszermag szerepe....................................................................................................93 6.1.2. A rendszermag struktúrája...............................................................................................94 6.1.3 A T.H.E. architektúra......................................................................................................96 6.1.4. A szolgáltatáskérések formái.........................................................................................101 6.2. Megszakításkezelés............................................................................................................105 6.3. Alacsony szintű ütemezés..................................................................................................107 6.4. Tárkezelési funkciók..........................................................................................................110 6.5. Perifériakezelés..................................................................................................................112 6.5.1. B/K vezérlőprogram......................................................................................................112 6.5.2. A B/K--szolgáltatások hívása........................................................................................114 6.5.3. IBM 360/370 OS/MVT vezérlőtáblázatok....................................................................114 6.5.4. A B/K--szolgáltatások befejezése..................................................................................118 6.6. Egyéb magfunkciók............................................................................................................119 6.7. Mintapéldák........................................................................................................................120 6.8. Gyakorlatok........................................................................................................................122 7. RENDSZERHÍVÁSOK..........................................................................................................123 7.1. Rendszerprimitívek............................................................................................................123 7.2. Folyamatként futó rutinok..................................................................................................124 7.3. Mintapéldák........................................................................................................................126 7.3.1. Az IBM 360/370 OS rendszerhívásai............................................................................126 7.3.2. A UNIX kernel rendszerhívásai....................................................................................127 7.4. Gyakorlatok........................................................................................................................130 8. ERŐFORRÁS-KEZELÉS......................................................................................................131 8.1. Alapelvek...........................................................................................................................131 8.2. Gazdaságosság...................................................................................................................131 8.3. Az erőforrások lefoglalása.................................................................................................132 8.4. Holtpont..............................................................................................................................133 8.4.1. A holtpont megelőzése..................................................................................................134 8.4.2. A holtpont felismerése...................................................................................................136 8.5. Korlátok, kompromisszumok.............................................................................................137 8.6. Mintapéldák........................................................................................................................138 8.6.1. Megelőzési algoritmusok..............................................................................................138 8.6.2. Holtpontfelderítő algoritmus.........................................................................................139 8.7. Gyakorlatok........................................................................................................................140 9. PROCESSZORKEZELÉS......................................................................................................141 9.1. Alapfogalmak, az ütemezés eszközei.................................................................................141 9.2. Ütemezési szintek...............................................................................................................144 9.3. Ütemezési algoritmusok.....................................................................................................145 9.3.1. Előbb jött -- előbb fut....................................................................................................146 9.3.2. A legrövidebb előnyben................................................................................................147 9.3.3. Prioritás.........................................................................................................................147 9.3.4. Körben járás..................................................................................................................148 9.3.5. Többsoros ütemezés......................................................................................................149 9.4. Értékelési módszerek.........................................................................................................150 9.5. Gyakorlatok........................................................................................................................154

10. TÁRKEZELÉS.......................................................................................................................155 10.1. Abszolút címzésű rendszerek.............................................................................................155 10.2. Áthelyezhető címzésű rendszerek......................................................................................155 10.3. Particionált rendszerek.......................................................................................................156 10.3.1. Rögzített partíciók (MFT).............................................................................................158 10.3.2. Változó partíciók (MVT)..............................................................................................159 10.4. Tömörítés...........................................................................................................................159 10.5. Lapozás és szegmentálás....................................................................................................160 10.6. Virtuális tár.........................................................................................................................164 10.7. Lapozási stratégiák.............................................................................................................168 10.7.1. Lapcsere algoritmusok..................................................................................................168 10.7.2. Keretkiosztási algoritmusok..........................................................................................169 10.8. Tárvédelem.........................................................................................................................170 10.9. Mintapéldák........................................................................................................................172 10.9.1. Tömörítés, dinamikus relokáció....................................................................................172 10.9.2. Szegmenstáblák.............................................................................................................172 10.9.3. Kombinált megoldások.................................................................................................172 10.9.4. Az optimális lapozás közelítései...................................................................................174 10.9.5. Egyéb megfontolni valók..............................................................................................175 10.10. Gyakorlatok........................................................................................................................176 10.11. Appendix: A cc-NUMA, a VLMS és társai.......................................................................178 11. ÁLLOMÁNY- ÉS OBJEKTUMKEZELÉS...........................................................................179 11.1. Állományok és állományrendszerek..................................................................................179 11.2. Adatok, perifériák és folyamatok.......................................................................................180 11.2.1. Állományokon végezhető műveletek............................................................................181 11.2.2. Katalógusok és katalógusrendszerek.............................................................................182 11.2.3. Elérési módszerek.........................................................................................................184 11.2.4. Háttértár-kiosztási módszerek.......................................................................................185 11.3. Adatvédelmi rendszerek.....................................................................................................189 11.4. Háttértárak kezelése...........................................................................................................189 11.4.1. FCFS ütemezés..............................................................................................................190 11.4.2. Legközelebbi előnyben.................................................................................................190 11.4.3. A SCAN algoritmus......................................................................................................190 11.5. Mintapéldák........................................................................................................................191 11.6. Gyakorlatok........................................................................................................................192 12. KONKURENS FOLYAMATOK............................................................................................193 12.1. Párhuzamosság és szinkronizálás.......................................................................................193 12.2. Szoftver megoldások..........................................................................................................194 12.3. A folyamatok hierarchiája..................................................................................................196 12.4. A kritikus szakasz problémája............................................................................................199 12.5. Szemaforok........................................................................................................................204 12.6. Folyamatközi kommunikáció.............................................................................................206 12.7. Mintapéldák........................................................................................................................209 12.7.1. Termelő--fogyasztó probléma.......................................................................................209 12.7.2. Író--olvasó probléma.....................................................................................................210 12.7.3. Az Accent operációs rendszer.......................................................................................210 12.8. Gyakorlatok........................................................................................................................212 12.9. Appendix: Monitorok.........................................................................................................213

13. RENDSZERHATÁSFOK VEZÉRLÉS..................................................................................217 13.1. Az IBM SRM alapelvei......................................................................................................217 13.2. A szolgáltatás egysége........................................................................................................219 13.3. Terhelési szintek.................................................................................................................220 13.4. Terhelési sablonok és végrehajtási csoportok....................................................................220 13.5. Végrehajtási periódusok.....................................................................................................222 13.6. Intervallumokra bontott kiszolgálás...................................................................................222 13.7. Tartományok......................................................................................................................222 13.8. Rendszercélok és taktikák, rendszerhangolás....................................................................223 13.9. Gyakorlatok........................................................................................................................224 14. VIRTUÁLIS GÉPEK..............................................................................................................225 14.1. Több operációs rendszer egy gépen...................................................................................225 14.2. Megvalósítási kérdések......................................................................................................226 14.2.1. A hardver emuláció problémái......................................................................................226 14.2.2. Hypervisor funkciók......................................................................................................228 14.2.3. Működésoptimalizálás...................................................................................................229 14.3. Kapcsolat az elosztott rendszerekkel.................................................................................229 14.4. Mintapéldák........................................................................................................................230 14.4.1. Az IBM VM/CMS interaktív fejlesztő rendszer...........................................................230 14.4.2. Osztott hálózatok, mint virtuális gépek.........................................................................231 14.4.3. Emulátorok -- a gépszimulátorok..................................................................................231 14.5. Gyakorlatok........................................................................................................................232 IRODALOMJEGYZÉK................................................................................................................233 INDEX .........................................................................................................................................235 ÁBRAJEGYZÉK 1.1. ábra. 1.2. ábra. 1.3. ábra. 2.1. ábra. 2.2. ábra. 2.3. ábra. 3.1. ábra. 3.2. ábra. 3.3. ábra. 3.4. ábra. 3.5. ábra. 3.6. ábra. 3.7. ábra. 3.8. ábra. 3.9. ábra. 3.10. ábra. 3.11. ábra. 3.12. ábra. 3.13. ábra. 4.1. ábra. 4.2. ábra. 4.3. ábra. 4.4. ábra. 4.5. ábra.

A rendszerekkel kapcsolatos fogalmak szemléltetése..................................................4 A számítógépes rendszer rétegződése a problémamegoldáskor...................................7 A számítógépes rendszer rétegződése az üzemeltetésnél.............................................7 Az operációsrendszeri szoftver rétegződése...............................................................23 Szoftvermegszakítás...................................................................................................27 Az MS--DOS hierarchikus katalógusrendszere..........................................................43 Egyfelhasználós rendszer tárfelosztása......................................................................54 Spooling......................................................................................................................56 Az IBM OS/MFT tárkezelése.....................................................................................57 Az IBM OS/MVT ütemezési viszonyai......................................................................57 Lapkezelés..................................................................................................................59 Szegmensek................................................................................................................59 Folyamatállapot diagram............................................................................................60 Kötegelt rendszert vezérlő kártyacsomag...................................................................61 Teljes kapcsolású hálózat............................................................................................66 Részleges kapcsolású hálózat.....................................................................................66 Csillaghálózat.............................................................................................................66 Gyűrűs hálózatok. a) Egyszeres, b) Többszörös.........................................................67 Busszal rendelkező hálózat.........................................................................................67 Munkafogadás............................................................................................................72 Munkakiválasztás.......................................................................................................73 Programfordítás..........................................................................................................74 Programszerkesztés....................................................................................................74 Programaktiválás és erőforrás hozzárendelés.............................................................76

5.1. ábra. Alrendszeri rétegződés...............................................................................................85 5.2. ábra. Az alrendszer kiépítés elemzése.................................................................................86 5.3. ábra. Számítógépes rendszerek strukturálódása..................................................................87 6.1. ábra. A T.H.E. architektúra rétegei......................................................................................99 6.2. ábra. Round-Robin (körben forgó) ütemezés három programmal....................................107 6.3. ábra. Szabadlánc-struktúra az IBM OS/MVT-ben.............................................................113 6.4. ábra. Az IBM 360/370 OS/MVT vezérlőtáblázatai...........................................................116 7.1. ábra. Primitívként futó funkciók működése......................................................................124 7.2. ábra. Folyamatként futó funkciók működése....................................................................125 8.1. ábra. Biztonságos, bizonytalan és holtponti állapot..........................................................136 9.1. ábra. Folyamatállapotok....................................................................................................142 9.2. ábra. Átkapcsolás (context switch)....................................................................................142 9.3. ábra. Várakozó sorok és láncolt listák...............................................................................143 9.4. ábra. Központi egység ütemezés.......................................................................................144 9.5. ábra. A közbenső szintű ütemezés hatása..........................................................................145 9.6. ábra. Időosztásos ütemezés................................................................................................148 9.7. ábra. Többsoros ütemezés.................................................................................................150 10.1. ábra. Dinamikus relokálás relokációs regiszterrel.............................................................156 10.2. ábra. Multiprogramozás helycserével (swapping).............................................................156 10.3. ábra. Swapping pufferezéssel............................................................................................157 10.4. ábra. Tömörítés..................................................................................................................159 10.5. ábra. Logikai lapok, laptábla és fizikai lapkeretek............................................................160 10.6. ábra. Kódmegosztás lapozásnál.........................................................................................161 10.7. ábra. Szegmenscím ellenőrzés bázis/limit regiszterpárral.................................................163 10.8. ábra. Logikai szegmensek, szegmenstábla és fizikai szegmensek....................................164 10.9. ábra. Laptáblázat virtuális tárkezelésnél...........................................................................165 10.10. ábra. Lapkeresés és belapozás...........................................................................................166 10.11. ábra. Kilapozás..................................................................................................................167 10.12. ábra. Laphiba-sorozat példa..............................................................................................168 10.13. ábra. Optimalizált laphiba-kezelés....................................................................................169 10.14. ábra. Címellenőrzés határregiszterekkel............................................................................171 10.15.a) ábra. Címzési hiba két határregiszter esetén......................................................................171 10.15.b) ábra. Címzési hiba bázis/limit regiszterpárnál...................................................................171 10.16. ábra. Szegmentált lapozás.................................................................................................173 10.17. ábra. Lapozott szegmentálás..............................................................................................174 10.18. ábra. A legrégebben használt lap kilapozása (LRU algoritmus).......................................175 11.1. ábra. Fa-struktúrájú katalógusrendszer..............................................................................183 11.2. ábra. Fa-struktúra kapcsolatokkal......................................................................................184 11.3. ábra. Folytonos helykiosztás a lemeztárakon....................................................................186 11.4. ábra. Láncolt helykiosztás a lemeztárakon........................................................................187 11.5. ábra. Indexelt helykiosztás a lemeztárakon.......................................................................188 12.1. ábra. Precedenciagráf........................................................................................................194 12.2. ábra. Az elágazás (fork) precedenciagráfja.......................................................................194 12.3. ábra. Az egyesítés (join) precedenciagráfja......................................................................195 12.4. ábra. Tiszta fork/join szerkezet........................................................................................196 12.5. ábra. Folyamatok dinamikus létrehozása..........................................................................197 12.6. ábra. Hatelemű precedenciagráf........................................................................................212 12.7. ábra. A monitorok koncepciója.........................................................................................213 13.1. ábra. Az IBM 370 OS/MVS ütemezői..............................................................................218 13.2. ábra. Terhelési szintek, terhelési sablonok és végrehajtási csoportok az SRM-ben.........................................................................221 14.1. ábra. Több operációs rendszer egy gépen.........................................................................226 TÁBLÁZATOK 2.1. táblázat. CP/M, UNIX és MS-DOS összehasonlító táblázat....................................................49 7.1. táblázat. Az IBM 360/370 OS néhány rendszerhívása...........................................................126 7. táblázat. A UNIX kernel tipikus rendszerhívásai....................................................................128

OS$EV06.RTF,2001-04-16,ZSP ELŐSZÓ Mottó: "Az elefánt nem más, mint egy egér, IBM operációs rendszerrel! " -- Barron.

Könyvünket bevezető tankönyvnek szánjuk, ezért igyekszünk nem túl mélyre ásni az operációs rendszerek elméletébe, amelyről sok tekintetben ma is elmondható, hogy nem alakult ki eléggé. A téma tárgyalását a 80-as évek elején megjelent, új -- "második generációs" -- operációs rendszer szakkönyvekben terjedő irányzathoz igazítottuk. Míg a korábbi könyvek egy-egy konkrét operációs rendszerhez kapcsolódtak, addig az új generáció megpróbálja általánosítva összefoglalni a szakma -- különösen a mikrogépek forradalma kapcsán szétzilálódott -- ismereteit. Tárgyalásmódunkkal kapcsolatban megjegyezzük még, hogy "európai logikát" követünk, amennyiben egy-egy téma bemutatásánál általában az elméleti alapokból indulunk ki, és csak később adunk gyakorlati példákat. Az operációs rendszerekről sokan úgy beszélnek, mint szükséges rosszról (lásd Barron idézetét). Ugyanakkor a mai alkalmazók zöme csupasz hardvert még sose látott, és aligha tudna vele mit kezdeni. A hardvert tökéletesen elfedi előlük a szoftver, amelynek legalapvetőbb része a (többnyire operációs rendszerként emlegetett) rendszerszoftver. Barron nyomán kijelenthetjük, hogy a mai számítógép alkalmazóknak maga az operációs rendszer "a gép"(!). Az operációs rendszerek történetileg az akkor még méregdrága nagyszámítógépek jobb kihasználása végett születtek. Fő elvük ezért a hardver hatékony kihasználásának biztosítása volt. Közben -- az árak zuhanásával, majd a minik és mikrók megjelenésével -- a körülmények erősen megváltoztak. Ma a felhasználó jó kiszolgálása fontosabb szempont, mint a hardver hatékony üzemeltetése. Az operációs rendszerekre vonatkozó erős kritikai megjegyzések alapja éppen az, hogy a nagygépes operációs rendszerek meglehetősen rugalmatlanul reagáltak erre a kihívásra, ami a minik és mikrók erős térnyeréséhez vezetett. A miniszámítógépes, de különösen a mikroszámítógépes korszak operációs rendszerei sokkal jobban idomultak az új követelményekhez. Gyökeresen új szoftver megoldásokat hoztak létre az erőforrásszegény környezetre, teljesen elrugaszkodva a nagygépes tapasztalatoktól. Mindezek eredményeképpen a Barron által már a korai operációs rendszerek kapcsán is ostorozott "ad hoc" jelleg csak tovább terebélyesedett, és a kialakult anarchiában alig lehet valami rendszerezést végrehajtani. Nem csoda, hogy a korai -- "első generációs" -- operációs rendszer szakkönyvek inkább praktikus célokat követtek. Véleményünk szerint sem lehet a kialakult helyzetben egyszer s mindenkorra rendet teremteni, így a mi tárgyalásmódunk is vita tárgyát képezheti. Ezért, lehetőség szerint, megpróbáljuk rendszerezni a témakör legfontosabb alapelveit, majd példák kapcsán bemutatni az eltérő megvalósítási módokat. Eközben érintjük a legújabb irányzatokat is (IBM OS/2, UNIX verziók, NOVELL, stb.), de kerüljük az iránymutató jóslatokat. Néhány, általunk hasznosnak vélt tanácsot azért elmondunk.

Könyvünk a SZÁMOK oktatási rendszerében az "Operációs rendszerek" tantárgy hallgatói segédkönyve, és egyben az oktatók támogatására is szolgál. Az anyag mennyisége meghaladja a hallgatóktól elvárt követelményeket, az előadóra bízzuk, hogy a rendelkezésre álló óraszámmal és a konkrét gépi környezettel összhangban szelektáljon. A fejezetek végén található mintapéldákat és gyakorlatokat az oktatók a gyakorlati órák anyagának kialakításánál, valamint egységes szemléletű vizsgatételek összeállításánál hasznosíthatják. A könyv anyaga támaszkodik a SZÁMOK "Számítógép alapismeretek" című tankönyvére, jóllehet, néhány hardver fogalmat újra áttekint az operációs rendszerek szemszögéből nézve. Az egyes fejezetekben szándékosan ismétlésekbe bocsátkozunk. Vannak olyan nehezebb fogalmak, amelyeket érdemes több oldalról is körüljárni, más és más megvilágításba helyezni. Ez segítheti az anyag rögzítését. A tárgyalás elsősorban a programozóképzés szempontjait veszi figyelembe, de úgy véljük, hogy könyvünkből a számítógépes szakma minden tagja hasznos ismereteket szerezhet. Ezt a megjegyzést bátorításnak szánjuk, minthogy az operációs rendszerek sokak számára valami homályba vesző, megérthetetlen szoftver kolosszusok. Mi megpróbálunk rávilágítani a csillogó cseppkövekre ebben a misztikusnak tűnő barlangban. Reméljük, sikerül! Megemlítjük még, hogy a könyvet a híres WORD szövegszerkesztővel írtuk, amelynek kényelmeit igen megszerettük. Sajnos -- meglepetésünkre -- a könyv tükörnyomata eleinte nem akart tökéletes lenni a STAR Laser Printer 8-as nyomtatónkon. A szövegben jobboldali szövegkizárási problémák adódtak. Több eset volt lehetséges: 1) vagy mi nem olvastuk el eléggé a dokumentációt, 2) vagy a magyar ékezetek érvényesítése miatt feltétlen megírandó nyomtató interfész programban vétettünk hibát, 3) vagy a lézernyomtató nem úgy működik, ahogy gondoltuk, és 4) végső esetben a Word is lehet hibás. Végül a térköz (SPACE) karakter mérete okozta a problémát. Mindenesetre az itt vázolt a hibaelemzési sorrendet figyelemre méltónak tartjuk mások számára is: az ember mindig a saját munkájában kerese először a hibát, csak aztán a másokéban -- és legkevésbé a rendszerszoftverben vagy a hardverben. A programozási feladatokban erősen rá vagyunk utalva, hogy legalább bizonyos elemi eszközök működésében higgyünk. Hiba észlelése esetén azonban tanácsos jól elgondolkodni (ha ez időben kiderül, nem úgy mint esetünkben), hogy a hiba nem veszélyezteti-e alapjaiban a projekt megvalósítását. Olykor segít a hibák kiismerése, és kicselezése. Ez ugyan nem túl vígasztaló szöveg az operációs rendszerekről írott könyv előszavában, de az Olvasónak a valós életkörülményeket szeretnénk inkább megmutatni. Egyébként, ahogy egy kollégánk egyszer megjegyezte: "a rendszerprogramozás nehéz kenyér". Kemény munka -- kevés siker. Azért mégis elég sokan csinálják -- szerencsénkre!

Budapest, 1989. február

A szerzők

A “commemorial e-text” átírásnál az ismert sajtóhibák kijavításra kerültek, és az összes ábrát átrajzoltam text-art megoldásúra. A szöveg az eredeti mű fejezetenkénti szövegeit tartalmazzák. Terveim szerint a jelenlegi .RTF formátum helyett a még hordozhatóbb Adobe .PDF formátumra konvertálom, tehát végül e-book lesz belőle. Budapest, 2001. április

Zsadányi Pál

OS01V10.rtf,2001-04-16,ZSP

1. BEVEZETÉS

1.1. Rendszerek és struktúrák Az operációs rendszer kifejezés kapcsán érdemes elidőzni kicsit a rendszer fogalmánál. Az irodalomban -- a számítástechnikaiban egyenesen előszeretettel -- igen sok helyen használják a rendszer szót. Sokszor előfordul, hogy több témáról van szó, és az ember nem is érti, hogy éppen melyikre céloz a szöveg a rendszer szó használatakor. Ez alkalmas arra, hogy a témában gyakorlatlan olvasót teljesen összezavarja. Hogyan keletkezik egy rendszer? Nyugodtan kimondhatjuk, hogy egy rendszer megalkotásához az ember rendszerező képessége szükséges. A valós világból -- amelyben minden mindennel összefügg -- az ember választ ki olyan részt, amely az éppen vizsgált szempontból összefügg. A vizsgálati szempontot az ember adja meg, és a létrehozandó rendszerbe illőnek azt tartja, ami ebből a szempontból lényeges szerepet játszik. Amit nem tart lényegesnek, azt elhanyagolja. (Az elhanyagolás persze nem feltétlenül pontos, ami hibát okozhat.) Az ember, amikor rendszert alkot, rögtön két részre bontja a világot: az általa vizsgált rendszerre és a világ - számára most érdektelen - többi részére. Így szerkezetet (struktúrát) visz az eddig szerkezetnélküli mindenségbe. Egy rendszer természetesen újabb szempontok alapján további elkülöníthető részekre osztható. Ezek a mondottakból következően ugyanúgy rendszerek, mint az első szempont szerint elkülönített része a világnak. Ilyenkor azonban megkülönböztetésül igyekszünk valamilyen szóösszetételt alkalmazni: alrendszer, részrendszer, rendszermodul stb., vagy a funkciója szerint adunk nevet a vizsgált résznek. A valós világnak azt a részét, amely lazán kapcsolódik a vizsgált rendszerhez, a rendszer környezetének nevezzük. Ha egy rendszerbe belevesszük a környezetét (amely ilyenkor annak részrendszerét képezi), olyan rendszert kapunk, amelynek nincsenek külső kapcsolatai, azaz zárt rendszer. Ellenkező esetben nyílt rendszerről beszélünk. Egy rendszert nem szoktunk minden határon túl felosztani. Vizsgálati szempontjaink rendszerint azt is kitűzik, hogy mi lesz a legrészletesebb felosztás. A legrészletesebb felosztásban szereplő rendszerrészeket elemeknek, vagy komponenseknek nevezzük. A vizsgált rendszer statikusan az elemek felsorolásával és a közöttük lévő esetleges kapcsolatokkal írható le. A kapcsolatok jellemzik a rendszer struktúráját.

A rendszer és a környezete közötti érintkezési felületen (interfészen) fellépő kapcsolatok a vizsgálat szempontjából rendszerint különös jelentőséggel bírnak. Az ilyen kapcsolatok jellemzésére szolgál az interfészleírás. A részrendszerek kapcsolatait szintén interfészleírásokkal lehet megadni. Az eddig mondottakat szemlélteti az 1.1. ábra. +------------------------------------------------------------+ | VALÓS RENDSZER (Valós világ, Reálszféra) | |

+-----------------------------------+

|

|

|

| (1)

|

|

|

+- - - - - - · - - - - - - - - - - -+

|

| (2)

|

|

|

|

|

+-I-·-n-·-t-·-e-·-r-·-f-·-é-·-s-·-z-+

|

|

|

+-----------------------------------+

| R

E

N

D

S

Z

E

R

|

| |

| E11E12

E13

E14

E15

|

| | | (3)

|

| E21

E22

|

E31E33 E32

E34

|

| |

|

| | K

Ö

R

N

Y

E

Z

E

T

|

| | +------------------------------------------------------------+ 1.1. ábra. A rendszerekkel kapcsolatos fogalmak szemléltetése Az ábrán zárójelekbe tett számok különböztetik meg a részrendszereket, a rendszerelemeket Ebetűvel kezdődő szimbólum jelzi, az elemek kapcsolatát pedig nyilak mutatják. A vizsgált rendszer dinamikus leírását mozgásának megadásával lehet rögzíteni. A rendszerben tevékenységek zajlanak, amelyek egy vagy több folyamatba csatlakoznak. A folyamatok különféle (rendszer)funkciókat valósítanak meg, azaz végrehajtódásuk valamilyen eredménnyel jár. Ha a rendszer tevékenységei céltudatosak, akkor a folyamatok valamilyen vezérlési elvek szerint haladnak. A vezérlés során a folyamatok döntési pontokon haladnak át és elágazhatnak, vagy ciklikusan ismétlődhetnek, amíg a kívánt eredmény meg nem születik. A működés erőforrásokat igényel. A rendszer folyamatai ezért versenyeznek a rendszer erőforrásaiért: vagy használják az erőforrást vagy várakozásra kényszerülnek az erőforrás foglaltsága miatt (sorban állnak az erőforrásért). A vizsgált rendszer folyamatai időbeli lefolyásuk szempontjából az alábbiak szerint osztályozhatók:

a) Soros folyamatok azok, amelyek időben egymásután zajlanak, és időben nem fedik át egymást (de szünet lehet közöttük): F1 F2 F3 F4 >---------->*>-------->······>---------->*··>------->* (szünet) b) Párhuzamos folyamatokról van szó, ha azok időben egymást átlapolva futnak, illetve ha egy adott pillanatban mindegyikük él: F1 >------------------------------------->* F2 >---------------->* F3 >--------/·····/---------------------------->* (várakozás) c) Szinkron folyamatokról beszélünk, ha a folyamatok olyan kapcsolatban állnak egymással, hogy valamelyik (a szinkronizáló) kiváltja mások (a szinkronizáltak) működését (szinkronjel) (a szinkronizáló folyamat sokszor meg is hal, lásd: F3-->F4): F1 >----+-----------+-----------+------>* | szj. | szj. | szj. v v v F2 F3 F5 >---->* >--->* >--->* | szj. v F4 >----------->*

szinkronizáló

szinkronizált párhuzamosak (szj.= szinkronjel, (*= STOP) szinkronizált soros

d) Aszinkron folyamatok párhuzamosan futnak, és nem függnek egymástól. e) Izokron (egyidejű) folyamatoknak hívjuk az olyan párhuzamos folyamatokat, amelyek mindegyike működik egy adott időintervallumban. f) Ütemezett, párhuzamos (szimultán, konkurens, versenyző) folyamatoknak nevezzük az olyan párhuzamos folyamatokat, amelyek közül mindig csak egy-egy halad, esetleg van közöttük egy, amelyik a többi működését vezérli (ütemező): Ütemez ő: F1: F2:

>-+.....+---+.....+-+...+-----+...+--+..¸ | | | | | | | | | >-----+...|.....|.+---+.....+--->* | | | | >-----+..................+-- ...¸

Ez a helyzet akkor áll elő, ha a vezérelt folyamatok közös erőforráson osztozkodnak, így ennek a folyamattípusnak különösen fontos szerepe van az operációs rendszerekben. Észrevehetjük, hogy az ütemező (Ü) a folyamatokat soros részfolyamatokra tördeli: Ü > F1.1 > Ü > F2.1 > Ü > F1.2 > Ü > F1.3 > Ü > F2.2 ...

Gyakorlati példa a sakkszimultán, ahol egy nagymester több sakkozóval játszik. Akár statikusan, akár dinamikusan akarunk leírni egy vizsgált rendszert, a leírást csak közelítéssel tudjuk elvégezni. A rendszerek ilyen leírását rendszermodellnek nevezzük. A modell leírásához használt módszerek alapján a modelleket osztályozni szokták. A számítástechnikában számunkra leghasznosabbak a matematikai modellek, amelyek a vizsgált rendszer legobjektívebb leírását adják (feltéve, hogy az elhanyagolások helyesek voltak). A rendszermodellekben alapvetően háromféle rendszerstruktúrát különböztetünk meg: Elsőként az egymástól független vagy egymással egyenrangú (rész)rendszereket említjük, amelyeket párhuzamos struktúrájúaknak nevezhetünk. Példaként a párhuzamos iskolai osztályok (I.a, I.b ...) említhetők. A második esetet képező, egymástól függő, egymásra épülő (rész)rendszereket hierarchikus struktúrájú rendszereknek nevezzük. A hierarchia azonos szintjén szereplő párhuzamos részrendszerek réteget alkotnak. A hierarchiában az alsóként ábrázolt rétegek valósítják meg a rendszer egyszerűbb funkcióit, amelyekre a felsőbb rétegek bonyolultabb funkciói épülnek. Tisztán hierarchikus rendszerekben csak szomszédos rétegek állnak kapcsolatban egymással a réteginterfészeken át. A felsőbb rétegek az alsóbbakat a réteginterfészeken át dinamikai szempontból szolgáltatáshalmazként használják (rétegszolgáltatások). Az iskolai példánál maradva, a felsőbb osztályokban oktatott tananyagok az alsóbb osztályokban elsajátított tudásanyagra támaszkodnak. Az iskolarendszer tehát többé-kevésbé úgy rétegződik, hogy az otthon és az óvodában szerzett ismeretekre számít az általános iskola, míg az (egymással párhuzamos rendszereket képező, különféle típusú) középiskolák az általános iskolai tudásanyagra, a felsőoktatás pedig ezek összességére épül. A példában szereplő hierarchia nem tiszta, mert a legfelsőbb szinten is közvetlenül használjuk a legalsóbb szinteken szerzett ismereteket. A harmadik esetet a strukturálatlan rendszerek képezik, amelyeket nevezhetünk inkább bonyolultnak is. Ez az eset tulajdonképpen azoknál a (rész)rendszereknél merül fel, amelyek szerkezetét még nem tártuk fel vagy szerkezetük számunkra érdektelen. Egy rendszer szerkezetének meghatározásánál egyszerű és világos struktúrára törekedjünk. Az ilyen rendszerekre azt mondjuk, hogy jól strukturáltak. Ez azonban mindig csak a felmerült szempont alapján igaz, és akkor is csak közelítéssel. Például a hierarchikus modellek akkor jól strukturáltak, ha egy réteg folyamatai csak a közvetlen alatta elhelyezkedő réteg szolgáltatásait veszik igénybe, és soha nem fordulnak annál mélyebb vagy a náluk magasabb rétegek szolgáltatásaihoz. A "VALÓS RENDSZER" felosztását mutató ábránkon az (1)-es alrendszer a vizsgált rendszerben a hierarchia tetején áll, a (2)-es és (3)-as alrendszerek egymással párhuzamosak, tehát egy réteget alkotnak. A környezetet képviselő részrendszer a hierarchia legalján szerepel. A példánkban vizsgált modell tehát háromrétegű, és zárt rendszert képez.

Vizsgált rendszerünk elemeinek kapcsolatát irányított gráf matematikai modellel ábrázolhatjuk. A kapcsolatrendszer lehet teljes (amikor minden elemnek minden elemmel van kapcsolata), lehet szabályos (pl. lineáris, hurkolt, fa alakú stb.) és lehet szabálytalan. A hierarchikus kapcsolatokat hurokmentes fa alakú gráfok írják le. (Az utóbbi szerkezet az operációs rendszerek szempontjából különösen fontossá vált.) Lineáris gráf

Hurkolt gráf

Hierarchikus gráf

E1E2E3E4 E1-->E2-->E3 | | | | E6 >aa bb cc dd ee ff gg >*>.........>*>...............>* 1. szegmens 2. szegmens 3. szegmens ... Lapleképezés a valós tárra: oo oo oo oo bb aa ff ee (oo=operációs rendszer!) >--+--+--+--+--+.....+--+--+--> Operatív tár (lapokra tördelve) A logikai és fizikai címtartomány nemcsak a virtuális címzés problémáját vetette fel a hardverekben. A virtuális címzési technika feltételezi, hogy a processzor nagyobb címtartomány átfogására képes, mint az operatív tár valódi címtartománya. Vannak azonban olyan processzorok is, amelyek nem tudják egyszerre megcímezni az operatív tár teljes címtartományát. Ilyenkor különleges hardvereszközzel, a társzervezéssel és csatlakozó operációs rendszeri szoftverrel teszik lehetővé a teljes operatív tár elérését. Az egyszerre elérhető tárrészt szegmensnek hívják. (Vigyázat! Ez a szegmensfogalom nem egészen azonos a virtuális címzésnél használt szegmensfogalommal!) A fizikai címtartományban a szegmens tényleges helyét egy speciális regiszter, a szegmensregiszter jelöli ki: Teljes operatív tár >-------------------*--------------------------------------> | szegmensregiszter | >-------------------> szegmens A társzervezést egyes hardverekben kombinálják a virtuális címzéssel is (pl.: INTEL 80286/80386!), ami igen rugalmasan konfigurálható számítógépes rendszerek létrehozását biztosítja. Az utasításrendszer a hardverrétegben mindazon utasítások összessége, melyeket a központi egység végre tud hajtani. Bár az utasítások szerkezete gépenként nagyon változatos lehet, a legtöbb utasítás egy utasításkódból és egy vagy több címből áll. Míg a régebbi processzoroknál az utasításkészlet néhány tucat utasításra korlátozódott, a mai rendszereknél általában több száz különböző utasításkód használható. Az utasításkódon és a cím(ek)en kívül gyakran valamilyen járulékos információ is szerepel az utasításban (például: címzési mód, indexelés, indirekció stb.). Tipikus utasítás-beosztás: +------------+-------------+---------------+ | Műveletkód | Címzési mód | Címek | +------------+-------------+---------------+ Minél bonyolultabb egy központi egység utasításkészlete, annál rövidebben lehet hozzá gépi kódú

programokat írni. (A gépi kódút azért hangsúlyoztuk ki, mert a gyakorlati tapasztalat szerint a fordítóprogramok írói nem merik kihasználni a hatékonyabb hardver utasításokat, s ezért a magas szintű nyelvek nemigen profitálnak belőlük! Rendszerint az a probléma, hogy a fordítóprogramoknak a gépcsaládok legalacsonyabb modelljein is működő kódokat kell generálniuk.) Az egyszerűbb utasításkészlet gyorsabb dekódolást tesz lehetővé, ami nagysebességű utasítás-végrehajtást eredményez. Ezért és a magas szintű, portabilitást biztosító programozási nyelvek fokozottabb térnyerése miatt manapság terjednek a csökkentett utasításkészlettel rendelkező számítógépek (angolul RISC = Reduced Instruction Set Computers, velük szemben állnak a komplex utasításkészletűek (CISC = Complex Instruction Set Computers). A csökkentett utasításkészletet úgy határozzák meg, hogy lehetőleg minden utasítás egyforma hosszúságú legyen, és egyetlen gépi utasításciklus alatt végrehajtódjon. Bonyolultabb utasításokat csak akkor engednek meg, ha azok használata nagyon jelentős előnnyel jár. A komplex utasításkészletek alkalmazása azonban még napjainkban is meghatározó hardverirányzat. Az újabb -- a mai hardver fejlődést döntően meghatározó (MOTOROLA, INTEL) -- mikroprocesszorok is kifejezetten bonyolult utasításkészlettel rendelkeznek (a nagyobb gépeknél ez a természetes!). Az operációs rendszerek egyrészt messzemenően figyelembe veszik, másrészt általában kibővítik az eredeti utasításrendszert. A bővítés elvileg azt jelenti, hogy az eredeti hardverutasítások segítségével programozott új utasítások új -- az eredeti gépi kódban kihasználatlan -- kóddal hajthatók végre. A bővítést megvalósító programokat mikrokódnak, mikroprogramoknak is nevezik. Az így létrehozott virtuális központi egység sok egyéb lehetőséget is tartalmazhat. Igen általános -- és az operációs rendszerek védelmi rendszerének megszervezéséhez nélkülözhetetlenül fontos -- több működési állapot megvalósítása. Ezek közül leggyakoribbak a kétállapotú architektúrák. Normál állapotban a bővített utasításkészletnek csak egy részhalmaza használható, míg privilegizált állapotban a teljes utasításrendszer rendelkezésre áll. A privilegizált állapotot az IBM 370-en például "supervisor állapot"-nak, a Honeywell-en "master mód"-nak hívták. A privilegizált állapot legtöbbször megszakításokkal kapcsolatos, sok hardverben a megszakítás fellépése kiváltja a privilegizált állapotba való átmenetet is. Természetesen szükség van olyan utasításra is, amely normál állapotban mesterséges megszakítást és ezzel állapotváltást idéz elő (ilyen például az IBM 370 SVC utasítása). Az ilyen utasításokat használják az úgynevezett szoftver megszakítások programozásához. Többnyire csak privilegizált állapotban hajhatók végre a B/K utasítások, valamint a gép megszakításokra adott reakcióját befolyásoló parancsok. A megszakítási rendszerre azért van szükség, mert a számítógépes rendszerek olyan alkatrészeket is tartalmaznak, amelyek párhuzamosan is működtethetők. Gondoljunk például a B/K műveletekre! Ezek egyrészt időigényesek, másrészt általában csak indítást igényelnek a központi egységtől, végrehajtásukról pedig külön processzorok (csatornák) gondoskodnak. A probléma gyökere az, hogy az elindított transzfer végét hogy lehet észlelni. Elképzelhető lenne olyan megoldás, hogy megvizsgáljuk időnként a perifériát, hogy foglalt-e még. Kérdés, hogy milyen időközönként vizsgáljuk. Ha sok perifériával kell egyidejűleg foglalkozni, akkor a processzor egyebet se csinálna, mint állandóan csak a perifériákat figyelné ciklikusan. Hasznos tevékenységre alig maradna ideje. Jobb, ha a periféria jelez akkor, amikor kész az átvitel, hiszen akkor csak egyszer kell foglalkozni a perifériával. A processzor éppen folyó munkáját persze meg kell szakítani ahhoz, hogy a transzfer végén szükséges teendőket el tudjuk végezni.

A megszakítási rendszer ezért lehetővé teszi: * a reagálást a központi egységen belül fellépő speciális feltételekre (pl.: processzorhiba feldolgozását, ami lehet nullával való osztás, vagy nem létező bájtra való hivatkozás eredménye), * a kívülről érkező jelzések (megszakításkérelmek) kezelését, és ezek által * a párhuzamosan üzemeltethető egységek közötti koordinációt. A megszakítások kezelését a hardver- és szoftvereszközök igen változatos keveréke végzi bonyolult algoritmusok alapján. Minden megszakító rendszer azonban azt az alapvető problémát oldja meg, hogy egy véletlenszerűen bekövetkező esemény képes legyen megváltoztatni a műveletek végrehajtási sorrendjét az éppen elvégzés alatt álló művelet eredményének elvesztése nélkül. A megszakítás tehát tulajdonképpen hardver úton erőltetett vezérlésátadást (ugrást) jelent a megszakítást feldolgozó, ún. megszakító rutinra. A megszakító rutin indulása előtt azonban rögzíteni (menteni) kell a központi egység állapotát, hogy azt a megszakítás feldolgozása után vissza tudjuk állítani úgy, hogy az eredeti programot hibátlanul folytathassuk (ha ennek van értelme). A központi egység állapotát minden pillanatban egy rögzített hosszúságú állapotvektorral lehet jellemezni (utasításszámláló, regiszterek, állapotjelzők tartalma). A megszakító rutin hívása általában ugrótáblán (hardveres zsargonban megszakítási vektoron) keresztül valósul meg, ahova a vezérlés a megfelelő megszakítás bekövetkezésekor hardver úton adódik át. Az ugrótáblából a megszakító rutin átveheti a működéséhez szükséges paramétereket is. A megszakítási rendszert főleg az teszi bonyolulttá, hogy egy megszakítás feldolgozása közben újabb megszakítási kérelem is érkezhet, amivel a rendszernek szintén foglalkoznia kell. Ez a jelenség jóformán tetszőleges mélységben egymásba skatulyázva is felléphet. A problémát a gyakorlatban úgy egyszerűsítik, hogy bizonyos (például processzor hiba) megszakítások kezelésének idejére letiltják minden más (de legalább az adott osztályba tartozó) megszakítás fogadását. Ez azt jelenti, hogy ha ismételten ilyen megszakítási kérelem érkezik, akkor ezt a központi egység várakoztatja az éppen feldolgozás alatt álló processzorhiba lekezelésének befejezéséig. Ugyanakkor természetes, hogy valamilyen megszakítás kezelése közben a központi egység más osztályba tartozó megszakításokat elfogad. Egy nyomtató működése közben például egy lemez-adatcsere kényelmesen lefolytatható. Azt, hogy a megszakító rutinok is megszakíthatók legyenek, úgy oldják meg, hogy az állapotvektort veremként működő tárba mentik. Ez jórészt szoftver úton megy végbe, de az első lépésekhez hardver támogatásra is szükség van. (A régi utasításszámláló értéket csak a hardver tudja félretenni, a program nem!) A veremből mindig az oda utoljára beírt állapotvektor emelhető ki (az ilyen vermet angolul LIFO = Last In First Out stacknek hívják), a veremmutató pedig automatikusan átáll az eggyel mélyebben elhelyezett elemre. A skatulyázott megszakításoknál ez a verem teszi lehetővé a megfelelő helyre való visszatérést valahányszor egy megszakítás feldolgozása befejeződött. A megszakítások feldolgozása azonban még így sem problémamentes, mivel az állapotvektor mentésének ideje alatt a rendszer "védtelen" egy újabb megszakítással szemben. Kézenfekvő megoldás, hogy erre a rövid időre letiltjuk a megszakításokat. A letiltást addig kell fenntartani, amíg a megszakító rutin el nem ér egy olyan biztonságos pontra, ahol az újabb megszakítás már nem zavarhat.

A megszakítás menete sematikusan a következő: * megszakítási kérelem érkezik a központi egységhez; * a központi egység a kérelmet várakoztatja, amíg egy utasításciklus be nem fejeződik, vagy amíg az adott osztályú megszakítás tiltott; * amikor a központi egység elfogadja a megszakítást, segít félretenni a megszakított program állapotát jelző állapotvektort a megfelelő verembe; * automatikusan privilegizált állapot jön létre, és legalább az adott osztály megszakítása letiltódik; * a megszakítási osztálynak megfelelő megszakítási vektorból a központi egység előveszi a megszakító rutin induló állapotvektorát, és a megszakító rutin első utasítására adja a vezérlést; * a megszakító rutin befejezi az előző program állapotvektorának mentését, ha ezt a hardver nem végzi el tökéletesen, majd elkezdi a megszakítás-kérelem okának felderítését és a szükséges teendők elvégzését; * amint a megszakítás feldolgozása túl van a kritikus szakaszon, visszaállítja az adott osztály megszakíthatóságát; * a megszakítás feldolgozása rendszerint azzal ér véget, hogy a vezérlést átadja valamilyen más programnak, ami többnyire az operációs rendszer valamelyik ütemező rutinja; * az ütemező dönt a folytatásról, és előveszi a folytatni szándékozott program állapotvektorát a veremből, majd a vezérlést a program megszakítását követő utasításra adja. A megszakításkezelés nyilvánvalóan határterületen van, jó megszakítás-kezelő rendszer csak a hardver- és szoftvertervezők harmonikus együttműködésétől remélhető. Ezen együttműködésből származó néhány -- azóta általánosabban elterjedt -- ötlet ma is figyelemre méltó: * A központi egység állapotának mentése helyett több regiszterkészletet építenek a processzorba. * Megszakításokat engedélyező egyszerűen manipulálhatók.

maszkok

bevezetése,

amelyek

logikai utasításokkal

* Egymást nem zavaró megszakítási osztályok bevezetése és az osztályok fontossági sorrendbe állítása (prioritás). * Az utasításszámláló regiszter tartalmának közvetlen (ugró utasítás nélküli) módosíthatósága. Minden esetben az a közös cél, hogy a rendszer minél kevesebb ideig legyen elvágva -- megszakítás fogadására alkalmatlan állapotban -- a külvilágtól. Védelmi mechanizmusra azért van szükség, hogy megakadályozhassuk a számítógépes rendszerben a programok hibás működéséből eredő károsodásokat vagy a felhasználók illetéktelen beavatkozásait. A probléma tipikusan a multiprogramozásnál fordulhat elő (a felhasználók ilyenkor tudnak "egymás levesébe belekanalazni"). Figyelembe kell venni még azt is, hogy az operációs rendszer és a felhasználó programja eleve "párhuzamosan" fut, ami végeredményben kétszeres

multiprogramozást jelent. A védelmi mechanizmusok alapvetően háromfajta védelmet nyújtanak: a központi egység, az operatív tár és a B/K műveletek védelmét. A központi egység védelme a felhasználói programok említett ésszerűtlen viselkedése miatt fellépő veszélyek elhárítását célozza. Ha például a program végtelen ciklusba kerül, az operációs rendszer nem kapja meg a vezérlést bizonyos, periódikusan ismétlődő feladatainak (például a képernyőtartalom frissítése) ellátásához, ami nyilván nem megengedhető. A szokásos megoldás az úgynevezett óramegszakítás, amely szabályos időközönként generálódik. Az óramegszakítás lehet állandó (pl. 1/50 másodperc) vagy szabályozható időközű. Maga a megszakítás egy regiszterben való számlálással valósítható meg. Az órára vonatkozó műveletek természetesen csak privilegizált módban hajthatók végre. Normál állapotban az ilyen utasítások végrehajtása helyett a hardver megszakítja a program működését, mert hibának tartja a privilegizált utasítások végrehajtásának kísérletét. Az operatív tár védelme azt jelenti, hogy minden program csak a számára valamilyen módon kiosztott tárterületen dolgozhat, ha ezt a szabályt megsérti, megszakítás jön létre, majd az operációs rendszer be tud avatkozni. Azt, hogy ilyen fajta védelemre szükség van, nem kell különösebben indokolni, hiszen például súlyos esetben a felhasználói programok átírhatnák az operációs rendszer területének tartalmát, ami teljes anarchiához vezetne. A B/K műveletek védelme szintén megoldható privilegizált utasítások segítségével olymódon, hogy a külső egységekkel való adatcsere alsó szintjét csak privilegizált utasításokkal engedjük megvalósítani. Erre azért van szükség, mert különben egy hibás -- például az állomány végét nem érzékelő -- olvasóprogram megbéníthatná az egész rendszert. A közösen használható perifériák (mágneslemezek) használatát pedig eleve központilag kell koordinálni. A koordinálás csak akkor működik jól, ha minden igény egy pontban találkozik. Célszerűen a privilegizált üzemmódban működő operációs rendszerre kell rábízni a B/K koordinációját, normál állapotban működő alkalmazói programoknak pedig meg kell tiltani a B/K műveletek közvetlen használatát. Hangsúlyozzuk, hogy az operációs rendszerek védelmi mechanizmusai csak akkor működnek hatásosan, ha a processzor hardver úton, privilegizált üzemmód(okk)al támogatja. Nem lehet például az MS--DOS operációs rendszerben védett, multiprogramozott környezetet teremteni, mert az INTEL 8086/8088-as mikroprocesszoroknak nincs privilegizált üzemmódja. A dolognak az a szépséghibája , hogy az MS--DOS az AT gépeken sem használja ki az AT gépek fejlettebb INTEL 80286-os processzorának privilegizált üzemmódját. Ez példája annak, hogy egy rossz operációs rendszeri architektúra képtelen igazodni a későbbi hardverfejlődéshez, és gyakorlatilag a fejlődés gátjává válik. Az AT gépek hardver lehetőségeit igazán csak a UNIX operációs rendszer Microsoft változata, a XENIX tudja kihasználni (de a felhasználó elég drága árat fizet érte mind pénzben, mind az elrabolt hardver erőforrások tekintetében). A mondottakból világosan kitűnik, hogy az IBM PC-k multiprogramozható OS/2 (az MS--DOS utódját képező) operációs rendszere miért csak a privilegizált üzemmóddal felszerelt INTEL 80283/80383-as processzorokkal megépített IBM AT vagy PS/2 modelleken használható. A UNIX XENIX/86-os változata, és néhány más szoftver (konkurens DOS, NOVELL ANW86, PCUNIX stb.) lehetőséget teremt ugyan multiprogramozásra az XT gépeken, de hibás programok ellen nem tud védelmet nyújtani. Bele kell nyugodni, hogy az XT és az MS-DOS igazából csak egyfelhasználós, monoprogramozott környezetet biztosít. Maga az MS-DOS sem védett az ellen, hogy egy alkalmazói program esetleg tönkre tegye. Ellenkezőleg! Az MS-DOS kifejezetten igényli, hogy a jól képzett alkalmazói programozók "beletúrjanak" az operációs rendszer területébe, és/vagy közvetlenül mozgassák a perifériákat. Az így eluralkodott programozói stílus hosszú időre akadályozni fogja, hogy az ehhez szokott programozók rátérjenek védelmet biztosító operációs rendszerek (OS/2, XENIX) használatára.

1.4.2. Tárak Általános értelemben tárnak nevezünk minden adattárolásra használható eszközt, amellyel -- azt mondjuk -- írás és olvasás útján kommunikálni lehet. Mi a számítógépes rendszerekkel kapcsolatban a gép belső vagy operatív tárolóját (amelynek szavai vagy bájtjai az utasításkészlet számára elérhetők) hívjuk tárnak (angolul: memory), a mágneslemezek, mágnesdobok, mágnesszalagok és egyéb hasonló tárak esetében inkább a háttértár vagy a külső tároló (angolul: store) kifejezést használjuk. A tár a hardverréteg nélkülözhetetlenül fontos része, így nem véletlen, hogy egy számítógéppel kapcsolatban általában ez az első adat, amit megkérdeznek vagy megadnak. Az egyszerűbb rendszerekben (első és második generáció) a tárat mágnesdob, majd ferritgyűrűk (core memory) segítségével realizálták, és teljes kapacitása felett a felhasználó rendelkezett. Az operációs rendszerek megjelenése, a tárkapacitás növekedése azonban viszonylag gyorsan megváltoztatta ezt a helyzetet. A sok regiszterrel rendelkező központi egységekben a regiszterek halmaza tulajdonképpen valami gyors működésű tárként fogható fel, amely a központi egység és a tényleges operatív tár közötti adatcserét igyekszik gyorsítani. A gyors működésű regiszterek mintájára a legtöbb gépet továbbfejlesztették, ami más szóval azt jelenti, hogy az operatív tár sem egységes. Általában kis kapacitású, de rövidebb elérési idejű gyorstárból és az eredeti operatív tárból épül fel. A két tároló között legalább egy nagyságrend sebességkülönbség van, ugyanakkor a gyorstárak jóval drágábbak (viszont még mindig olcsóbbak, mint a regiszterek). A gyorstárat az egyes gyártó cégek általában saját elnevezésükkel látták el (buffer, cache, scratch pad stb.). A gyorstár kezelése erősen eltérő. Van, ahol a felhasználó is hozzáfér legalább egy részéhez, de sok esetben csak az operációs rendszer végzi az adatmozgatást a gyors és a normál operatív tár között. A processzor közvetlenül csak a gyors tárból dolgozik, s ha a hivatkozott adat nincs ott, a felhasználást egy implicit adatátvitel előzi meg az operatív tár és a gyorstár között. A rendszer teljesítménye szempontjából meghatározó a gyorstár találati valószínűsége. A mérések azt mutatják, hogy a találati valószínűség 5 %-os növelése a processzor utasítás-végrehajtási sebességét mintegy 25 %-kal is javíthatja. A gyorstárak gyorsító szerepének alapja a lokalitás elve: a számítógépes algoritmusokra jellemző, hogy viszonylag hosszú ideig foglalkoznak az operatív tár egy szűk környezetével. A félvezetős integrált áramkörök elterjedésével nőtt a tárak kapacitása és sebessége, csökkent az ára és fizikai mérete, így a tárakkal kapcsolatban egyéb szempontok -- elsősorban az elérési módok -kerültek előtérbe. Elterjedtek a csak olvasható (angolul ROM = Read Only Memory) tárak, amelyekben állandóan használt szoftverkomponenseket (pl. az operációs rendszer fontosabb rutinjait, fordítóprogramokat) tárolnak fixen. Egyes számítógépekben már a ROM előtt is alkalmaztak -- erősen korlátozott módon -- ún. átírható tartalmú tárakat (például a Burroughs B1700 gépében) a látható architektúra változtatása céljából. Ezek utódja az integrált áramkörök korában a PROM és az EPROM, a törölhető, programozható tár, melynek tartalma csak rendszeren kívüli folyamattal, elektronikus programozással írható át (beégetés). A ROM és (E)PROM eszközök lehetővé tették, hogy a mikroprogramokat a hardverréteg alá rejtsük, illetve, hogy a hardver architektúrát is programozott úton oldjuk meg egyszerű utasításkészletű mikroprocesszorokra támaszkodva. Ez teremti meg a számítógépes rendszer intelligenciájának korábbi lehetőségeknél jobb szétosztását is. Jellemző erre az intelligens terminálok létrejötte és a mikroprocesszorok megjelenése a korábban csak huzalozott elektronikát (logikai áramköri kapcsolásokat) tartalmazó perifériákban. Huzalozott elektronikát ma már csak akkor alkalmazunk, ha a sebességtényezők ezt indokolják, mert a huzalozott elektronika mindig gyorsabb működést biztosít, mint a mikroprogramozott, ugyanakkor sokkal drágább, és lassabban fejleszthető ki, hibája javíthatatlan.

Míg a ROM és az (E)PROM nemfelejtő, statikus tárak, azaz a gép kikapcsolt állapotában is megőrzik tartalmukat, a hagyományos operatív tár szerepét az ún. RAM (Random Access Memory), a véletlen elérésű (és rendszerint a tartalom folyamatos frissítésére szoruló) tárelem vette át, amely a feszültség kikapcsolása után elveszti tartalmát. Az összkapacitást már megabájtokban mérik, a tárchipek kapacitása pedig 256-1024-4096 kilobit, sőt -- a közeljövő nagy ugrásaként! -- 16 Mbit (1989!). 1.4.3. Háttértárak Általános jellemzőjük a nagy statikus tárolókapacitás, a viszonylag lassú és esetenként korlátozott hozzáférés. A fejlődés során először a már csaknem elfelejtett mágnesdobok jelentek meg, majd a mágnesszalagok korszaka következett. A mágnesszalagok hatalmas tárolókapacitása (amit tulajdonképpen csak a szalag hossza determinál) sokat enyhített azon a hátrányon, hogy csak szekvenciális adatelérésre adtak lehetőséget. Nagy adathalmazok archiválására ma is használatosak. A mindennapi használatban a szalagot a mágneslemezek elterjedése szorította vissza. Ezek előnye, hogy valamivel kisebb -- de még mindig több 100 megabájtos -- kapacitás mellett elfogadhatóan gyors, véletlen elérést biztosítanak (a véletlenség arra utal, hogy a tárolt adatok nagyjából egyforma időn belül hozzáférhetők, függetlenül attól, hogy véletlenül melyikre van éppen szükség). A cserélhetőség feladásával az elérési idő tovább csökkent, a fix és cserélhető lemezek kombinációja pedig minden rendszer számára megvalósíthatóvá tette az alkalmazási környezethez legjobban illeszkedő tárlókonfiguráció kialakítását. Az ún. winchester rendszer, valamint a hajlékony cserélhető lemezek bevezetésével a nagygépek mellett a mini- és a mikrogépek is megkapták olcsó, gyors és elég megbízható, nagy kapacitású háttértáraikat. (A CD-ROM-ot még akkoriban fedezték föl.) A mágneslemezek megjelenése az operációs rendszerek szempontjából döntő jelentőségű volt, mert a drága és kis mérető operatív tárakban nem lehetett túl sok adatot tárolni, a sorkezelési adatok mágnesszalagos tárolása pedig elviselhetetlenül lassú működést eredményezett volna. A mágneslemezek a véletlen elérési lehetőségeikkel egyszerű megoldást kínáltak a kötegelt és multiprogramozott környezetben felmerülő sorok kezelésére. 1.4.4. Egyéb perifériák A számítógépes rendszerhez kapcsolható készülékek igen nagy változatosságot mutatnak, mi azonban csak a legfontosabbakkal, a nyomtatókkal, képernyőkkel, billentyűzetekkel és adatátviteli vonalakkal foglalkozunk. Ezek legfontosabb közös tulajdonsága, hogy bájtonkénti adatátvitelt igényelnek. A nyomtatók minden számítógépes rendszer nélkülözhetetlen részei. Az írógépből kiindulva, a sornyomtatókon keresztül a mátrix, majd a lézernyomtatókig sokat fejlődtek és nagy változatosságot mutatnak. Az operációs rendszerek általában megkülönböztetett módon kezelik a nyomtatókat, összegyűjtik a nyomtatóra szánt adatokat, és külön menetben, más munkákkal párhuzamosan végzik el a listázást. A képernyő és a billentyűzet a manuális adatcsere eszközei. Ezek is a korábbi elektromos írógépből erednek, amely először a hardver vezérlésére szolgáló ún. főkonzol billentyűinek és kijelzőinek szerepét vette át. Így ragadt rá erre az operátori írógépre a konzolírógép vagy a még rövidebb konzol elnevezés. Később a papírt képernyő váltotta fel, de az írógép billentyűzet megmaradt. Az operációs rendszerek fejlődésének külön lökést adott a képernyős terminálok elterjedése, mivel így a nehézkes, kötegelt rendszereket a legtöbb alkalmazási területen a felhasználót segítő, interaktív rendszerek válthatták fel. Ez legalább egy hardvergenerációval felérő

fejlődés volt. A grafikus lehetőségekkel felruházott, finom felbontású, színes képernyő nagyban segíti az igazán barátságos (interaktív) alkalmazási rendszerek fejlesztését. Az adatátviteli vonalak a távközlési vonallal összekapcsolt számítógépek esetében játszanak fontos szerepet. Az adatátvitel itt is bájtonként megy végbe, a vonalra az adat egy modem közbeiktatásával jut. Az adatátvitelhez természetesen meglehetősen összetett szoftver tartozik, hiszen a kétoldalú kapcsolattartás -- főként a vonalhibák elhárítása miatt -- bonyolult feltételeket teremt.

1.5. Mintapéldák: hardverarchitektúrák A hardverarchitektúrákat (a történelmi fejlődés vonalán) a nagyszámítógépektől kiindulva, a miniszámítógépeken át a mikroszámítógépekig tekintjük át. 1.5.1. IBM 360/370, ESZR-I/II/III sorozatok Az IBM cég a hatvanas évek közepén vezette be 360-as gépeit, amelyek modelljei egy -- szoftverszinten erősen, hardverszinten kevésbé -- kompatibilis sorozatot képeztek. A 370-es sorozat ennek folytatásaként jelent meg, de csak korlátozott virtuális címzési lehetőségekkel haladta meg elődeit (a korlátozás azt jelentette, hogy a lapozás és a szegmentálás hardver úton nem támogatja a programok menet közbeni dinamikus áthelyezését, amire sok akkortájt gyártott hardver már képes volt -- pl.: ICL). A 370-es gépek új utasításokkal segítettek a nagy pontosságú tudományos számításoknál, és még a többprocesszoros üzemmód koordinációs problémáinak megoldására is felkészültek. Legújabb tagjaik a 4300-as és a 30xx-es inkább csak hardvertechnológiában és szoftver támogatásban különböznek. A keleti ESZR indulásakor IBM 360-as kompatibilitást tűzték ki célul, így az ESZR sorozatok szintén ebben az irányban haladnak. A processzor állapotát a programállapotszó (angolul PSW = Program Status Word) határozza meg, amely nyolcbájtos, és bitcsoportjai különféle processzorállapotokat reprezentálnak. A PSW végén három bájton szerepel a 24 bites tárcím. A maximális címezhető tár így 16 megabájt. A mai hardverfejlődés szempontjából ez meglehetősen kellemetlen korlát. A processzor utasításkészlete komplex, de eredetileg opcionálisan vásárolható részei is voltak, amelyek a későbbi modellekben és különösen az ESZR sorozatokban standard elemmé váltak. Az utasítások hossza és végrehajtási ideje erősen változó. Az utasítások hosszát félszóban mérik, ami két bájt. Egy, kettő és három félszavas utasítások vannak aszerint, hogy hány operandusa van az utasításnak, és milyen címzési módot használunk. Az utasítások a tárban csak ún. "félszóhatáron" helyezhetők el, azaz csak páros címeken kezdődhetnek. (A PSW utolsó bitje így mindig nulla.) Címzési rendszere elég egyszerű. Konstansmegadás, regiszteroperandus, báziskódolt és indexelt címzés használható csak. Erősen hiányzik az indirekt címzés. A virtuális címzési rendszer nem jelent külön címzési módokat, a programozónak a virtuális címkezelés "átlátszó". A B/K műveletek puffereinek azonban összefüggő "valós tárterületekre" kellenek, mert nem tudnak lapozni. A gépcsalád megszakítási rendszere óvatosan vektorosnak mondható, de csak öt megszakítási osztály vektorainak van hely. Az operatív tár alsó címeit a központi egység fix kiosztásban használja. A PSW elmentendő állapota megszakításkor a megfelelő fix címre kerül (régi PSW terület), majd a megfelelő osztály fix vektorcíméről (új PSW terület) kerül be a processzor PSW-be a megszakítás-kezelő program induló állapotát meghatározó státusszó. A státusszó megadja a megszakító program címét, és letiltja az adott osztályban a megszakítást. Ezzel a processzor vezérlése átkerül a megszakító programba, amely folytatja az állapotmentést a processzor regisztereinek és a régi PSW értékének elmentésével. Ez utóbbi után felszabadítható a megszakítás

tiltása az adott osztályban, mert a régi PSW vektor már elrontható. Védelmi rendszerével kapcsolatban már volt szó arról, hogy a processzornak két állapota van. A normál állapotot programállapotnak, a privilegizált állapotot pedig szupervizor (felügyelő) állapotnak nevezik IBM terminológiával. A privilegizált utasításkészlet csak szupervizor állapotban használható. A B/K műveletek a processzor működésétől függetlenül, több csatornán át, izokron és aszinkron módon folyhatnak. A processzor csak elindítja a transzfereket, és azok befejeződésüket megszakítás-kérelemmel jelzik. A tárvédelem 2 Kbájtos szegmensenként négybites tárvédelmi kulcs hozzárendelésével működik. Ez az operatív tárban egyidejűleg -- az operációs rendszer magjával együtt -- 16 program egymástól védett működését engedi meg. A nullás (0) tárvédelmi kulcsú tartományokban elhelyezkedő programoknak a tár bármely részéhez tetszőleges (írási, olvasási) hozzáférési joguk van. Természetesen ezt a rendszermag, a szupervizor szegmenseinek tárolásánál használják, de ideiglenesen felhasználói programok egymás közti közlekedésének lebonyolításához is szükség lehet ilyen védelmi kulcsra. Ilyenkor feltételezik, hogy jól belőtt rendszerprogram működik a kritikus partícióban. 1.5.2. PDP 11, MSZR I/II, VAX, MSZR III sorozatok A miniszámítógépek a Digital Equipment Corporation (DEC) cég azon reklámötletéből erednek, hogy nem kell nagyobb hardverkapacitást vásárolnunk, mint amit a feldolgozásunk igényel. Ennek nyomán a DEC elkezdett "lecsupaszított" gépeket gyártani, amelyek csökkentett utasításkészletű, kis sebességű processzort, kevés operatív tárat, minimális háttértárat és egyéb perifériát, rendszerint csak egy Teletype telexírógépet tartalmaztak. A telex írógép egyidejűleg négy perifériát tudott helyettesíteni: bevitelt billentyűzetről és lyukszalagolvasóról, valamint kivitelt írógépre és lyukszalaglyukasztóra. Az egész nagyon ökonomikus volt, és átütő sikert aratott, pedig a gépvásárlók addig erősen megszokták, hogy a számítógépekkel nagy számítógéptermeket szokás bebútorozni. Szerencsére a DEC a nagygépektől jobbára idegen piacot, a folyamatvezérlési környezeteket célozta meg, amelyekben eleinte tényleg nagyon egyszerű folyamatvezérlő programok üzemeltetésére volt igény. Természetes volt, hogy ezekhez kis kapacitású gépek lehetnek csak gazdaságosak. Később persze a folyamatvezérlési környezetek igényei is rohamosan növekedni kezdtek, úgyhogy a DEC is kénytelen volt minigépeinek teljesítményét növelni, de addigra már megnyerte a csatát a piacon. A DEC gépek telexírógépes perifériája kezdettől fogva interaktív használatot tett lehetővé, bár ez a folyamatvezérlő környezetben inkább szükségszerűségként merült fel. A minigépek tehát eleinte csökkentett utasításkészlettel rendelkeztek (PDP 11), de a későbbi fejlődés nyomán szintén elérték a komplex színvonalat (VAX). Címzési rendszerük már kezdettől fogva elég bonyolult volt, hogy a szűk utasításkészlettel minél hatékonyabb kódokat lehessen generálni. Egyes címzési módok igazodtak a folyamatvezérlési feladatokból eredő különleges sajátosságokhoz (veremkezelés, autoinkrement/dekrement). (Ezeket a hardverújdonságokat a mikroprocesszoros korszak később kapásból át is örökölte.) A címzési rendszerre erősen rányomja bélyegét, hogy a címbusz eredetileg 16 bites volt, ami csak 64 Kbájt, illetve PDP filozófiával 32 Kszó címzését tette lehetővé (azaz egy szó kétbájtos). Ráadásul bevezettek egy addig szintén szokatlan technikát, a tárcímekbe beágyazott perifériakezelést, ami a címtartomány felső címeiből 4 Kszót mindig elrabol. A későbbi PDP modellek társzervező modullal próbáltak úrrá lenni a helyzeten (PDP 11/40: 124 Kszó, PDP 11/70: 2 Mszó). A címzési problémákat persze a minigépeknél is csak a 32 bites korszak beköszöntése oldotta meg megnyugtatóan, amelyet még ráadásul virtuális címzéssel is kombináltak (VAX-ok). A 32 bites minigépeket úgy tervezték meg, hogy 16 bites üzemmódban is tudjanak szükség esetén dolgozni. A minigépek megszakítási rendszerének kialakítását szintén erősen motiválta a megcélzott alkalmazói környezet. A folyamatvezérlő környezetből érkező megszakítási kérelmek

szétválasztásához ugyanis erősen vektoros megszakítási rendszerre volt szükség, hogy a hardver segíteni tudja a megszakítási okok szétválogatását. Több szoftvermegszakító utasítás is van az utasításkészletben. Megszakításkor automatikusan a verembe kerül a megszakított program 16 bites programállapotszava és a 16 bites programszámláló, majd a vektorcímről betöltődik a programszámláló és a programállapotszó. Ezzel megtörtént az átkapcsolás a megszakítás-feldolgozó programra. A megszakító program végén egy speciális (visszatérés megszakításból -- RTI) utasítással elérhetjük, hogy a programszámláló és a programállapotszó értéke a veremből automatikusan visszatöltődjön, és a megszakított program folytatódjon. Így a visszakapcsolás is igen gyors. (A mikroprocesszorokban ezeket a tulajdonságokat is igyekeztek maximálisan átörökölni.) A kevés számú (végeredményben csak hat darab) 16 bites, általános regiszter mentése a megszakító rutinok feladata, de olykor a veremtároló regiszter mentése is szóba kerül. A védelmi rendszer természetesen itt eleve nem hiányozhat, hiszen erős multiprogramozás merül fel. Kettő vagy három, egyes minigépeknél még több processzorállapot is létezik. 1.5.3. INTEL 8086/8088, 80286, 80386 mikroprocesszor család Az INTEL cég a mikroprocesszorok atyja. Igazán azonban akkor "fogta meg az Isten lábát", amikor az IBM bekapcsolódott a mikroszámítógép üzletbe. Az IBM, hogy végleg le ne késsen az üzletről, lemondott a saját fejlesztésű alkatrészek alkalmazásáról, ami korábbi stílusától teljesen szokatlan volt. Az ügy nyertese az INTEL 16 bites, komplex utasításkészletű (CISC) mikroprocesszor családja lett. Ugyanakkor az IBM úgy látszik ezzel a húzással igyekezett gátolni a mikrók terjedését a 32 bites kategória irányába. Volt is féltenivalója a 32 bites IBM 3x minigépes kategóriájú gépcsalád miatt! A mai helyzet ismeretében ez a stratégia bevált. Az azonban nem vált be az IBMnek, hogy létrejött egy hatalmas hasonmás piac, amely az eredeti IBM gépeknél sokszorosan hatékonyabb, és ráadásul sokkal olcsóbb gépeket kezdett produkálni. Az INTEL mikroprocesszor család természetesen ebből is hasznot húzott. Addig is meg tudta vetni lábát a sokkal korszerűbb 32 bites mikroprocesszorokkal szemben, amíg létre nem hozta a családon belül a 32 bites családtagot, a 80386-os formájában. E mikroprocesszor család alapján ma mintegy tízmillió gép működik a világon (1989!). Az INTEL 8086-os volt a család kiinduló eleme. Ez a korábbi 8 bites INTEL processzorok vonalát folytatta a 16 bites tartományban. A processzor állapotát a regiszterkészlet és a programszámláló tartalma határozza meg. Megszakításkor a processzor automatikusan verembe menti a programszámlálót és a szegmensregisztert. Minthogy a 16 bites címbusz csak 64 Kbájt címzésére alkalmas, a 64 Kbájtnál nagyobb címek képzésére szegmentált társzervezést és nagyszámú címzési módot alkalmaznak. A 8086-os társzervezésében igen egyszerű "trükköt" találtak ki. Szegmenscímként csak 16-tal osztható címeket engednek meg. Az ilyen bináris címek utolsó négy bitje mindig nulla. Ezeket tehát fölösleges tárolni. Így a 16 bites szegmensregiszterekben tulajdonképpen 16+4=20 bites címeket tudunk tárolni, ha a társzervezőre rábízzuk, hogy a címet egészítse ki a végén négy nulla bittel. Kettőnek a huszadik hatványát kiszámítva belátható, hogy így maximálisan egy megabájtot lehet megcímezni. A PC korszak azonban nem több mint két év alatt kinőtte ezt az akkor meglehetősen nagynak számító címtartományt. Az INTEL sem volt rest, és a 80286-ban bedobta a fentebb tárgyalt trükk "meredekebb" változatát. Ha csak 256-tal osztható szegmenscímeket engedünk meg, akkor a 16 bites szegmensregiszterek egyenesen 24 bites, tehát 16 megabájtos címtartomány megcímzését teszik lehetővé. Minthogy előre látható volt, hogy a PC-k ezt a címtartományt is ki fogják nőni, az INTEL virtuális lapozást is beépített ebbe a mikroprocesszorba. A 32 bites architektúrájú 80386-os modell 32 bites címbusza 4 Gbájt címzését is lehetővé tenné minden nyakatekert trükk nélkül. Mégis, a felhasználók tárcímek iránti elborzasztóan növekvő igénye arra sarkallta az INTEL-t, hogy még ebbe a modellbe is beépítsen társzervezőt, ami -- mai szemmel nézve értelmetlenül nagy, --

64 terabájt nagyságú virtuális tárcímek kezelésére is lehetőséget nyújt. A 80286/80386-os processzorokat az INTEL úgy tervezte meg, hogy tudják a 8086-os processzor működését szimulálni, de annál jóval gyorsabban. A 80286-os bonyolultabb, virtuális lapozást tartalmazó címzési rendszere mellett azonban már tarthatatlan volt az az állapot, hogy az INTEL 8086 -- a korábbi 8 bites modellek vonalából eredően -- hardver úton nem támogatta a védelmi rendszer megvalósítását. A virtuális címkezelés mindenképpen szigorúan operációs rendszeri hatáskörbe vonandó tevékenység, amelyet a többi program elől el kell zárni. Ez csak privilegizált üzemmódok bevezetésével lehetséges. A 80286/80386-os INTEL családtagoknak vannak privilegizált üzemmódjaik. Ezekbe a processzorokba külön processzorállapot-regiszter (PSW = Processzor Status Word) került, amelynek két bitje határozza meg a privilégium szintjét. A két bit négy állapotot jelent, így az INTEL terminológia szerint a privilégiumok négy gyűrűt (angolul: ring) alkotnak. A legtöbb jogot biztosítja a nullás (0) állapot, majd az 1-es, 2-es fokozatosan kevesebbet, és a 3-as jelenti a normál állapotot. Az alkalmazói programok csak normál állapotban futhatnak, míg az operációs rendszer három alrétege használhatja az igazán privilegizált processzorállapotokat. Mint később látni fogjuk, ezt az OS/2 operációs rendszer kidolgozásakor tökéletesen ki is használták. Az eredeti 8086-os mikroprocesszor a tár első 1 kilobájtnyi területét megszakítási vektorcímek tárolására használja. Minden vektor két 16 bites címet (tehát összesen négy bájtot) tartalmaz. Az egyik cím egy szegmenscím, a másik egy szegmensen belüli ofszet. Megszakításkor a processzor félreteszi a verembe a 16 bites programszámlálót (ofszet), és a CS (Code Segment) programszegmens regisztert, majd a megszakítási vektorcímről betölti a programszámlálóba az ofszetet, a CS-regiszterbe pedig a szegmenscímet. Utána végrehajtja az e címen található utasítást, aminek feltétlenül megszakítás-letiltó utasításnak kell lennie, mert a hardver magától nem tiltja meg a megszakítást. A további kódban kell felismerni a megszakítás okát és feldolgozni a megszakítást. A megszakítást programozottan kezdeményezhetjük az INT utasításokkal. Az INTEL 8086-ra alapozott PC-k ezt intenzíven használják operációs rendszeri funkciók hívására. A fejlettebb családtagok privilegizált üzemmódja megakadályozza az INT utasítás említett használatát, de egyben sokkal tisztességesebb szolgáltatás hívási algoritmusok kialakítását teszik lehetővé. A privilégiumok megsértése és speciális hibás szituációk (hiányzó virtuális lap) miatt fellépő megszakítások feldolgozásával, és az ún. kapukon át történő közlekedéssel lehet a fejlettebb családtagok alapján jó védelmekkel felruházott hardver-szoftver rendszert létrehozni. Említettük, hogy a család mikroprocesszorainak komplex utasításkészlete van. E processzorok azonban még társprocesszorokkal (koprocesszorokkal) való együttműködésre is alkalmasak. Ilyen az aritmetikai koprocesszor, amely az aritmetikai műveletek gyorsítását teszi lehetővé, de más, pl. sejtprocesszoros gyorsítók szolgáltatásainak igénybevételére is "idomíthatók". Ez a lehetőség az utasításkészlet további alapos kibővítésére ad módot. Utánozhatók például az IBM 370-es processzorok utasításai, ami PC-ken nagygépi programok futását teszi lehetővé stb.

Kis kiegészítés 2000-ből (ZSP): Az Intel 386-os architektúra lényegében azóta sem változott koncepciójában, hiába jöttek gyorsabb változatok (486, Pentium-XXX stb.). Ami a fenti leírásból kicsit hiányzik, az a 386-os architektúra speciális üzemállapota, a VM86 virtuális gép üzemmód. Ez teszi lehetővé, hogy a régebbi, a Microsoft-nál 16-bitesként emlegetett, de ennél fontosabb, hogy kifejezetten egyfelhasználós koncepcióval készült programokat a mai multiprogramozható operációs rendszerek felügyelete alatt "karanténba" zárhassuk, hogy hibás működésük ne döglessze le az egész operációs rendszert. Ez a DOS-ablak a Windows rendszerekben, a DOS-compatibility box az OS/2-esben, és a DOS-emulátor a UNIX/LINUX-jellegű PC-s operációs rendszerekben.

Kiegészítés 2001-ből (ZSP): A hardverek egyre több, hajdan szuper-számítógépes architektúrákban megszokott allűrt vesznek föl, még asztali és hordozható kategóriában is. Ezek közül a harmadik évezredben döntő jelentőségű váltás a 64-bites aritmetika tömeges elterjedése amiatt, hogy az alkalmazásoknak hatalmas adattömegekkel kell megbirkózniuk (a 64 bit tehát az adatkezelés miatt vált fontossá, nem az aritmetikai pontossági igények növekedése folytán, persze, azokhoz sem rossz, ha már van!). A további fontos fejlődési tünet a hibatűrő, sőt, katasztófatűrő hardver-szoftver rendszerek elterjedése, egészen az asztali gépekig (RAID). Szintén fontossá vált a világméretű hálózatok futótűzszerű terjedésével a védelmi rendszerek javítása, amelyeket korábban csak a hadiiparban véltek igazán fontosnak. A számítástechnika belépése a tömegpiacra olyan negatív jelenségekkel is párosult, mint a számítógépes kriminalisztika (rosszindulatú programok: férgek, vírusok; rosszindulatú "szakértők": crackerek, bitbetörők stb.), amire csak a centrálisan működő operációs rendszerek adhatnak kellő választ, intenzív hardver támogatásokkal. A hatalmas adattömegek biztonságos kezelése automatizált mentő-felügyelő, és az adatelérésekhez igazodó sebességű hierarchikus tároló-visszakereső rendszereket igényel. A nagy megbízhatóságú eszközök érdekes módon felvetik az üzemeltetési feladatok kiadását olyan cégeknek, akik az üzemeltetést távvezérelten tudják professzionális szinten megoldani, mert náluk már elegendő tapasztalat tud összegyűlni, és a magas képzési költségeket is le tudják nyelni (a szolgáltatási díj rovására), amit kis cégek már képtelenek megoldani (de ez fölösleges is, csak szakember pocsékolás volna!).

1.6. Gyakorlatok 1.6.1.

Soroljuk fel az operációs rendszer legfontosabb célkitűzéseit!

1.6.2.

Milyen operációs rendszert kell tervezni ahhoz, hogy a magas szintű nyelveken programozóknak ne kelljen bináris (vagy hexa) tártartalmat elemezni a programbelövés során?

1.6.3.

Mikor jó egy fejlesztői környezet?

1.6.4.

Mi az összefüggés a megszakítási rendszer és a védelmi mechanizmus között?

1.6.6.

Mikor célszerű indirekt címzést használni?

1.6.7.

Mit nevezünk privilegizált utasításnak?

1.6.8.

Milyen problémát okozhatna, ha az alsó szintű B/K-t nem privilegizált utasítások valósítanák meg?

1.6.9.

Mi a megszakítás és miért van rá szükség a számítógépes rendszerekben?

1.6.10.

Hogyan védekezhet az operációs rendszer egy felhasználói program végtelen ciklusa ellen?

1.6.11.

Sorolja fel a ma használatos operatív tárak leggyakoribb típusait!

1.6.12.

Mi a különbség a ROM és a RAM működése között?

1.6.13.

Mi a különbség a ROM és a RAM alapvető alkalmazási területe között?

1.6.14.

Mi a gyorstár szerepe a számítógépes rendszerben, és mit jelent a lokalitás elve?

1. Milyen közös tulajdonsággal rendelkezik a nyomtató, a billentyűzet és a képernyő?

OS02V12.RTF,2KI.4.16.

2. AZ OPERÁCIÓS RENDSZEREK FUNKCIÓI

Az operációs rendszerek funkcióit (szolgáltatásait) a szakirodalom nem egységesen definiálja. Eleve megkülönböztethetünk azonban alacsony- és magas szintű funkciókat. Az alacsony szintű funkciók szolgáltatásait a programokból úgynevezett rendszerhívások segítségével vehetjük igénybe, míg a magas szintűeket vezérlőnyelvekkel és segédprogramokkal (rendszerközeli szoftverelemekkel) érhetjük el. A funkciókat osztályozhatjuk az alábbiak szerint: * primitívek: elemi,- atomi,- tovább nem bontható funkciók; * összetettek: több primitív funkcióra épülő bonyolultabb funkciók; * fő funkciók: relatíve önálló egységet képező, együttműködő funkciók összessége. Az operációs rendszeri funkciókat természetesen programok valósítják meg. Az operációs rendszerekben önkényesen az alábbi három fő funkció jelölhető ki: * rendszeradminisztráció, * programfejlesztési támogatás és * alkalmazói támogatás. A programfejlesztési támogatás és az alkalmazói támogatás a rendszeradminisztrációs funkciókra épül, ezért a vonatkozó rétegszerkezetet a 2.1. ábra mutatja. +---------------------------+---------------------------+ | Programfejlesztési │ Alkalmazói | | támogatás │ támogatás | +---------------------------+---------------------------+ | | | Rendszeradminisztráció | | | +-------------------------------------------------------+ 2.1. ábra. Az operációsrendszeri szoftver rétegződése

2.1. Rendszeradminisztráció Rendszeradminisztrációnak nevezzük magának az operációs rendszernek a működtetésével kapcsolatos funkciókat. Ezek közvetlenül semmire sem használhatók, csak a hardverlehetőségek kibővítését célozzák, illetve a hardver kezelését teszik kényelmesebbé.

A rendszeradminisztráción belül a következő összetett funkciókat jelölhetjük ki: * processzorütemezés: a CPU-idő szétosztása a rendszer- és a felhasználói feladatok (taszkok, folyamatok) között; * megszakításkezelés: a hardver-szoftver megszakításkérések elemzése, állapotmentés, a kezelőprogram hívása; * szinkronizálás: az események és az erőforrásigények várakozási sorokba állítása; * folyamatvezérlés: a programok indítása és a programok közötti kapcsolatok szervezése; * tárkezelés: a főtár, -- mint kiemelten kezelt erőforrás, -- elosztása; * perifériakezelés: a bemeneti/kimeneti (B/K ill. I/O) igények sorba állítása és kielégítése; * adatkezelés: az adatállományokon végzett műveletek segítése (létrehozás, nyitás, zárás, írás, olvasás stb.); * működés-nyilvántartás: a hardver hibastatisztika vezetése és a számlaadatok feljegyzése; * operátori interfész: a kapcsolattartás az üzemeltetővel. A konkrét operációs rendszerek a funkciókat másképpen oszthatják fel. Így például az IBM OS operációs rendszerek változataiban négy fő funkciót szoktak megkülönböztetni: a munkakezelést, a taszkkezelést, az adatkezelést és a rendszerstatisztikát. Az IBM OS munkakezelése tulajdonképpen a mi felosztásunk szerinti alkalmazói támogatáshoz tartozik. A taszkkezelés körülbelül a mi felosztásunk szerinti rendszeradminisztráció folyamatvezérlési funkcióját fedi le, bár a háttérben feltételezi a processzorütemezést, a megszakításkezelést, a szinkronizálást és a tárkezelést. Az OS adatkezelési funkciója sem pontos megfelelője a mi felosztásunkban szereplőnek, mert tartalmazza a perifériakezelést is (fizikai szintű I/O kezelést). A rendszerstatisztika egyrészt a hardverkarbantartást segíti, másrészt a számítóközpont ügyvitelét támogatja (számlázás a felhasznált erőforrások alapján). Mi a hardverkarbantartás igényeivel itt nem foglalkozunk. A felhasználóbarát operációs rendszerek (CP/M, PC/MS--DOS, UNIX stb.) használatakor alig kell foglalkozni a funkcionális felosztás részleteivel. Ezeket az operációs rendszereket a boltból készen veszik, és nagyon kevés felhasználó kísérletezik a rendszer módosításával. Továbbá módosítás esetén a rendszer nem lenne kompatibilis a piacon készen kapható programokkal, ami a hétköznapi alkalmazók számára nem kívánatos. Az operációs rendszerek tervezésekor az elemi funkciók kijelölése bonyolult feladat. Függ a hardver erőforrásoktól és az alkalmazói igényektől. Némely feladatra (például szerszámgépvezérlés, folyamatvezérlés) rendkívül egyszerű funkciókból felépülő "operációs rendszer" is elegendő. Az esetek túlnyomó többségében azonban ez nem így van. Mindenesetre a bonyolultabb funkciók működése mindig az elemi funkciókra épül, ezért a bonyolultabb funkciókat magasabb hierarchiaszinten tételezzük fel. Az elemi funkciókat és a hierarchiaszinteket úgy kell meghatározni, hogy a kialakuló rendszer minél kevesebb ismétlődést tartalmazzon, és minél rugalmasabban tudjon alkalmazkodni a felmerülő igényekhez. Az elemi és összetett funkcióknál egyaránt fontos kérdés, hogy mely funkciók kerüljenek egymás melletti hierarchiaszintre, és melyek legyenek különböző hierarchiaszinten. A rendszeradminisztrációs funkciókat a rendszermag valósítja meg, amelynek a szolgáltatásait a már említett rendszerhívásokkal érhetjük el. Erről részletesen később, főként a 6. és 7. fejezetben lesz szó.

2.2. Programfejlesztési támogatás Ahhoz, hogy egy számítógépet használni lehessen, előbb programokat kell hozzá készíteni. Az operációs rendszerek egyik speciális feladata ennek a programfejlesztésnek a támogatása.

A programfejlesztési támogatás funkciói azonban csak kis részben tartoznak a szűkebb értelemben vett operációs rendszer funkciói közé. Oda soroljuk viszont a rendszerhívásokat, amelyekkel a rendszeradminisztrációs szolgáltatásokat igénybe tudjuk venni. A programfejlesztést leginkább a számítógépes rendszer nyelvi szintje támogatja (szövegszerkesztők, programnyelvi eszközök). A továbbiakban nem a funkcionális felosztás részleteiből, hanem magának a programozási tevékenységnek az elemzéséből indulunk ki, a végén pedig összefoglaljuk a talált funkciókat. 2.2.1. A programozási munka részfeladatai A következő részfeladatok merülnek fel: 1) a probléma elemzése (adatszerkezetek, algoritmusok), 2) esetleg az algoritmus felbontása több részprogramra, 3) a (rész)program(ok) megírása alkalmas programnyelven, 4) a (rész)program(ok) belövése (modulteszt), 5) a részprogramok összeépítése (integrálás), 6) átadás üzemeltetésre. 2.2.2. Támogatások a problémaelemzéshez A problémaelemzéshez az operációs rendszerek általában nem nyújtanak külön támogatást. A korai rendszerekben nem is voltak ilyen eszközök. A későbbiekben megjelentek a problémadefiniáló nyelveket értő fordítóprogramok, továbbá adatdefiniáló és adatmanipuláló nyelvekkel igyekeztek segíteni az adatbázis--technikában használatos adatelemzést. Ezeket később az ún. integrált programfejlesztő rendszerek speciális problémadefiniáló eszközei és programgenerátorai követték. A problémaelemzés fázisában először a feladat nyers vázlatát (informális specifikációját) adják meg, amelyet követ az ennél jóval precízebb formális specifikáció. Ez az integrált programfejlesztő rendszerekben adatbázisba kerül. A formális specifikációt még egyszer ellenőrzik, hogy kielégít-e minden megrendelői igényt. A véglegesített formális specifikáció alapján kezdődhet az implementálás. Eközben kiválasztják a megfelelő szoftvertechnológiát (Jackson, Warnier, heurisztikus stb.), valamint a (rész)feladat(ok)hoz legjobban illeszkedő programozási nyelvet, majd megindulhat a programtervezés és a programozás (részei: a programírás, a belövés, a rendszerpróba és az átadás). 2.2.3. A programírás támogatása Említettük a részprogramokat. Az algoritmusok részprogramokra bontásával (a módszer neve: moduláris programozás) kisebb programokat kell belőni. Bonyolultabb feladatokat pedig rendszerint nem is lehet egyetlen programmal megoldani, ezért ezek megírását több programozó együttműködésével, ún. team(illetve csoport-)munkában végzik. A részekre bontásból további előny származik, ha észrevesszük, hogy a részfeladatok többször felhasználható programjaiból programkönyvtárakat hozhatunk létre. A későbbi feladatokban már e könyvtárakra támaszkodhatunk, mert belőlük a szükséges elemek átvehetők az új program(ok)ba. Ezzel programozói kapacitásigényt takaríthatunk meg, ami a szoftverkrízisként emlegetett veszély elhárításában jelentős szerepet játszhat. (A szoftverkrízis: az igényelt új és módosítandó programok száma rohamosabban nő, mint a programozói kapacitás!) A programok írására olyan programozási nyelveket használnak, melyeket a nyelvi szint már említett programnyelvi eszközei, a fordítóprogramok és az interpreterek értelmezni tudnak. (Ezek közül a feladat megoldásához legjobban illeszkedőt kell kiválasztani.) A fordítóprogram megérti az adott programozási nyelven írt programot, és ha hibátlan, lefordítja

olyan kódra (úgynevezett gépi kódra), amelyet a hardver értelmezni tud. A korai számítógépeken az így előkészített programmal már meg lehetett oldani a feladatokat. Az interpreter soronként értelmezi az adott programnyelven írt kódot -- többnyire -- anélkül, hogy gépi kódra fordítaná. Ezért ha interpretert használunk, a forrásnyelvű program azonnal használható feladatok megoldására. A fordítóprogramokat és az interpretereket nem tekintjük a szűkebb értelemben vett operációs rendszer részének. Persze a személyi számítógépek interpreter típusú BASIC rendszere egyben az adott gép operációs rendszere is. Benne integrálódnak a nyelvi funkciók és -- az egyszerűbb hardver és a kisebb igényű alkalmazás miatt szűk körű -- operációsrendszeri funkciók. A moduláris programozás és a programkönyvtárak használata létrehozott két speciális programot: * az ún. programszerkesztőt, amely programok modulokból való összeállítását végzi, és * a betöltőprogramot, amely a programokat közvetlenül a futáshoz készíti elő. Létrejöttüket az alábbiakban igyekszünk megindokolni. Vizsgáljuk meg először a programkönyvtárakat, amelyeket több szinten is használhatunk. A legalacsonyabb szint a forrásnyelvű könyvtárak alkalmazása, amikor a programok forráskódját (vagy annak egy részét) valamilyen módon könyvtárakból nyerjük. Egyes fordítóprogramok beépített forráskód-generálási lehetőségeket tartalmaznak (ezt preprocesszor- vagy makrotechnikának nevezik). A forráskönyvtárak használatát támogatják a programírásra használt szövegszerkesztő programok is, amelyekkel a szükséges könyvtári programrészek bemásolhatók programunkba. A fordítóprogramok eleinte a gépbe közvetlenül betölthető, komplett gépi kódú programokat generáltak (ezekben mind az utasításkódok, mind az operanduscímek véglegesek voltak). Később a fordítókat megtanították arra, hogy a forrásprogramot ne fordítsák le azonnal tiszta gépi kódra, hanem félig fordított kódot (a forráskódból kiindulva úgynevezett célkódot, más néven tárgykódot, angolosan object-kódot) állítsanak elő (amelyben a hardver utasítások gépi kódja szintén végleges, de a címek átcímezhetők maradnak). Ezáltal kevesebb kódot kell a fordítóval generáltatni, mert a programhoz a félig fordított programrészek tárolására használt tárgyprogram-könyvtárból hozzá lehet másoltatni a program működéséhez szükséges kész, további modulokat (az első ilyen modulok a perifériakezelő szubrutinok voltak). A tárgyprogram-könyvtárban tárolt, tárgykódú, lefordított modulok jóval kisebb helyet igényelnek, mint a forrás-szövegek, ami újabb előny. Eleinte ezek a tárgyprogram-könyvtárak egy-egy fordítóprogramhoz kapcsolódtak, és a fordítóprogram maga vette elő a szükséges modulokat. Hamarosan rájöttek arra is, hogy a programkönyvtári programok (szubrutinok) belső formátumát uniformizálni kell, mert akkor egy program különböző moduljait a részfeladathoz legjobban illő programnyelven lehet megírni. A különböző nyelveken írt modulok lefordítása után keletkező tárgymodulok az azonos formátum miatt egyetlen monolit programmá fűzhetők össze. Az összeállításhoz új program kellett: a programszerkesztő, amelyet az angol linkage editor elnevezés alapján kapcsolatszerkesztőnek is hívnak -- a szövegszerkesztőktől megkülönböztetendő. Ez az egyes programmodulokat (fő- és alprogramokat, szubrutinokat) egyetlen (vagy néhány) végrehajtható programmá fűzi össze. A korai rendszerekben ezt a végrehajtható modult végcímzett programnak is hívták, mert a program a végrehajtásakor a főtárnak pontosan arra a helyére került, amit a szerkesztő kijelölt neki. Ezen a multiprogramozás kialakulása után változtatni kellett, mert ott az a célszerű, ha a programok a főtár bármely helyén működőképessé tehetők. Ezért a mai programszerkesztők nem készítenek végcímzett programokat, hanem a végrehajtható programban megtartják a tárgymodulokban található, átcímzéshez szükséges (relokációs) adatokat. Az összeszerkesztett programok futás előtti átcímzéséhez pedig egy újabb program kellett: az ún. betöltőprogram. Ez teszi lehetővé, hogy a végrehajtandó program a kijelölt tárhelyen működőképes legyen. Ezt nevezzük dinamikus áthelyezésnek.

A programszerkesztőnek, a betöltőprogramnak és a tárkezelőnek nyilvánvalóan egyeztetett formátummal kell dolgoznia. Ezért, bár ezek a programok eredendően a nyelvi szinthez csatlakoznak, központi szerepük miatt a szűkebb értelemben vett operációs rendszer részének tekintik őket, tehát operációsrendszeri funkciók. A betöltő olykor ténylegesen az operációs rendszer magjában helyezkedik el (kézenfekvő módon a tárkezelés részeként). Itt kapcsolódnak a témához a rendszerhívások vagy más néven rendszerszubrutinok. A programozás során legsűrűbben használt funkciók programját nyilván érdemes állandóan a tárban tartani, és szubrutinként használni. A perifériák kezelése már a korai időkben is olyan bonyolult volt, hogy meghajtóikat eleve szubrutinként használták a programozók. Később az operációs rendszerek -- védelmi okokból -- ki is vették a programozók kezéből a perifériák közvetlen kezelésének a jogát. Mindezek miatt az operációs rendszerbe épült sok hasznos, vagy a védelmi rendszer miatt másképp megoldhatatlan funkció kódja, amelyek szolgáltatásait a már emlegetett rendszerhívások segítségével vehetjük igénybe. Mivel a tárvédelem az operációs rendszer szubrutinjainak normális behívását megakadályozná, speciális módszert kell használni a rendszerfunkciók hívására. A behívást rendszerint a hardver erre specializált utasítására, a szoftvermegszakításra alapozzák, ha egyáltalán van ilyen utasítása a hardvernek (az INTEL 8080-nak például nincs, ezért a CP/M-ben trükkökhöz kell folyamodni: szubrutinugrás az 5-ös címre). A paramétereket regisztereken vagy veremtárokon át adják át a hívott funkció szubrutinjának, majd az eredmények ugyanilyen módon jutnak vissza a hívóhoz. Tipikus szoftvermegszakító utasítások: SVC (IBM 360/370 és a velük kompatibilis gépek: ESZR, SIEMENS, ICL, HITACHI stb.), TRAPS (PDP 11, MSZR), INT (INTEL 8086 család). Ezeket általában nem közvetlenül használják, hanem valamilyen makrohívás keretében. A makró neve ilyenkor jellemző lehet az elvégzendő funkcióra (például TIME, WAIT, GETMAIN, MESSAGE stb.), és a makrokifejtés szervezi meg a makrohívás paraméterlistáján felsorolt változók átadását, majd a kívánt kódú operációs-rendszeri funkció behívását a szoftvermegszakító utasítással. A legalacsonyabb szintű funkciók első sorban ASSEMBLY nyelven állnak rendelkezésre, de az utóbbi időben terjednek az olyan lehetőségek, hogy magas szintű nyelvek is el tudják érni az alacsony szintű funkciókat. Tipikus eset a C rendszerprogramozási nyelv, amely a UNIX kapcsán fejlődött ebbe az irányba. A UNIX kernel szolgáltatásait alapvetően C függvények formájában szokták megadni, bár párhuzamosan ASSEMBLY szintű definíciók is használatosak. Ma már nem megy csodaszámba például, hogy a TURBO PASCAL-ból elérhetjük az MS--DOS funkciókat. Egyszerű funkcióhívási példát mutat a 2.2. ábra (IBM PC). Program Operációs rendszer +-----------+ +------------+ | | | Szoftver >>>4*nn>>>> Ugrótábla | | v | megszakítás > | | | | INT nn >>>>>>>>>>>>>>>> | | | |...........| | | | | Folytatás >| CPU 2 |---->>( 3 ) tekercs \__/___ +-------+ \__/___ | +---------------------------+ Átvitel kiíróra | V_ Lassú kiíratás +----------+ / \ +-------+ | Sor| ( 3 )---->>| CPU 3 |---->>| nyomtató | \__/___ +-------+ \____----\| ’Szoftver’ (on-line) SPOOLING .-----------. \___________/ | Diszk | \__^_|__^_|_/ ^ | ^ | | | | |

| | | | | V | V .----------+ +--|-V--|-V--+ +----------+ | Rendszer-|-->>--. (2) .-->>---->>| Rendszer-| | olvasó | |(1) CPU (3)| | nyomtató | +----------+ +------------+ \____----\| Három folyamat fut párhuzamosan: . rendszerolvasó (1) . feldolgozó program (2) . rendszernyomtató (3) Ez már (csak kicsit) multiprogramozás 3.2. ábra. Spooling Történetileg elsőként az egyfelhasználós rendszereknél már bevezetett ún. "spooling" technikát kell megemlíteni, amely egy lassú perifériára (pl. sornyomtatóra) való kivitelnél úgy küszöböli ki a központi egység állandó tétlenségét, hogy a kivitel először egy gyorsabb háttértárra (célszerűen lemezre) történik viszonylag rövid idő alatt, majd a főprogram tovább fut, és maga a nyomtatás más feladatokkal párhuzamosan, a központi egység "hulladék idejében" hajtódik végre. (A SPOOL egy betűszó, amely az IBM-től ered: a "Simultaneous Peripheral Operation On-Line" rövidítése, azaz egyidejű, on-line perifériaműködés, ami a korábbi időszak off-line üzemű nyomtatásának ellenpontjaként hangsúlyozza ki a nyomtatás programfutással párhuzamos, on-line voltát.) +-64 K--------------------------------+ | | | 22 K | | | +-------------------------------------+ | 6 K | | | +-------------------------------------+ | 4 K | +-32 K--------------------------------+ | | | | | O p e r á c i ó s | | r e n d s z e r | | 32 K | | | | (kicsit torzított méretek) | +-------------------------------------+ 3.3. ábra. Az IBM OS/MFT tárkezelése

+-256 K---------------+ Programmezőre 192 K maradt | Rezidens terület | Gyakran használt tranziensek +---------------------+ | 3. régió | +---------------------+ | | Munkasor táblázat | 2. szabad mező | | | Sorszám Tár Idő +---------------------+ | 2. régió | 1 60 K 10 +---------------------+ | | 2 120 K 8 | 1. szabad mező | | | 3 24 K 40 +---------------------+ | 1. régió | 4 160 K 30 +--64 K---------------+ | | 5 70 K 12 | S u p e r v i s o r | | | +---------------------+ 3.4. ábra. Az IBM OS/MVT ütemezési viszonyai Ez tulajdonképpen már multiprogramozás, azzal a megszorítással, hogy az egyik program egy speciális rendszerkomponens, a spooling rutin. A világon a legelterjedtebb spooling rendszert az OS/360 alrendszereként Houstonban fejlesztették ki, és HASP-nak (Houston Automatic Spooling Program) nevezik. A HASP mind a kártyaolvasót, mind a nyomtatót kezeli, sőt a távfeldolgozó vonalak késleltetett üzenettovábbítása is a feladatkörébe tartozik (RJE). A multiprogramozott rendszerek meglehetősen bonyolultak. Ha több munkát akarunk futáskész állapotban tartani, akkor azoknak egyszerre kell a tárban lenniük, tehát az eddigieknél komplexebb tárkezelőre van szükség. Ha több munka is készen áll a végrehajtásra , ki kell választani közülük azt, amelyik a központi egység ütemezését megkaphatja. Ezen túlmenően a multiprogramozás vezérlése során gazdálkodni kell a külső egységekkel, kezelni kell a "holtpont" helyzeteket (amikor több felfüggesztett munka olyan eseményre vár, amit csak a munkák valamelyike tudna előidézni, de nem tud), a párhuzamos folyamatok szinkronizálását és különböző védelmi kérdéseket. 3.4.2. Tárkezelési problémák A tárkezeléssel a 10. fejezetben foglalkozunk részletesebben, most inkább csak a megoldandó problémákat vetjük fel. Az természetesnek tűnik, hogy a futtatandó programoknak áthelyezhetőknek kell lenniük. Ezt általános formában a logikai és a fizikai címtartományok bevezetésével lehet megoldani. A kulcskérdés a kettő közötti leképezés. Megoldható a multiprogramozás úgy is, hogy egyidejűleg csak egy munkát tartunk a tárban, amely így az operációs rendszer által szabadon hagyott teljes területet uralhatja. Az ilyen esetben használt technikát "swapping"-nak nevezik (magyarul: cserebere). A swapping lényege, hogy munkaváltáskor a felfüggesztett munkához tartozó teljes tárterületet a háttértárra másolják, és onnan behozzák a következő munkát. Itt háttértárként csak mágneslemez jöhet szóba, bár az első ilyen rendszerekhez még mágnesdobot használtak.

Amikor a swappingnál bevezették a több puffer használatát és a B/K tevékenységek idejét hasznos központiegység-munkával fedték át, eljutottak a többpartíciós multiprogramozáshoz. A tárat több, különböző méretű, egybefüggő részre (partíciókra) osztották, melyek mindegyikében egy végrehajtásra váró munka foglalt helyet. Attól függően, hogy a felosztás rögzített vagy változtatható, beszélünk fix vagy változó particionálásról. Prototípusként az IBM OS/360-ban megvalósított algoritmusokat szokták említeni, melyek megfelelő angol nyelvű rövidítése az MFT (fix partíciók) és az MVT (változó partíciók). Az MFT algoritmus egyszerűbb, de csak akkor hatékony, ha számítógép-rendszerrel folyamatosan majdnem egyforma munkakeverékeket akarunk megoldani. Az MVT bonyolultabb ütemezést és védelmet igényel, viszont bármilyen munkakeverékhez képes alkalmazkodni. Bármilyen ügyes algoritmusokat is dolgoztak ki a particionált tár kezelésére, a tár elaprózódása ellen nem lehetett hatásosan védekezni. Egy bizonyos idő elmúltával, a tárban sok, össze nem függő, apró terület alakult ki, melyeket bár együttes méretük számottevő volt, mégsem lehetett hasznosítani. A megoldást a virtuális tárkezelés megvalósításával bevezetett lapkezelés jelentette. A tárat azonos méretű lapokra osztják (a tipikus lapméret 2 Kbájt). Minden munkához annyi -- nem szükségképpen folytonos fizikai címeken elhelyezkedő -- lapot rendelünk, amennyit igényel. A lapkezelő alrendszer fő feladata a felhasználó logikai tárigényét leképezni a fizikai lapokra. A lapkezelés általánosítása a szegmentálás volt, ami tulajdonképpen változó méretű lapokkal folytatott gazdálkodást jelent. Bevezetésének másik oka az, hogy a lapozás néha az algoritmusokat kellemetlen ponton vágja ketté, így a programrésznek állandóan két lap között kell ugrálnia. Egy új szegmens használatával biztosítható, hogy a kritikus rutin egy lapra kerüljön. Max +-Fizikai tár-+ Változatlan marad | | +---------------+ | | | [3]| | | +-----+ . | [2] v [5]d | | | CPU |->|p|d| +->|f|d|------>| -*-Végcím - | +-----+ | | | | | Eltolás | p|Pointer | | | d|(Displace-| | +---+ | | [4]f | | ment) | |[1]+---+ | +--------->+==*=Alapcím==| | +---+ | A fizikai | | | +---+ | lap címe | | Index +-->+-f-+---+ | | (Pointer) +---+ Címtranszformáció| | +---+ [1]-[5]lépés | | +---+ | | +---+ | | Laptáblázat 0 +-------------+ 3.5. ábra. Lapkezelés

LOGIKAI SZEGMENTÁLÁS

.--------------------PROGRAM--------------------. +----------+ \ +-----------+ | Szubruti-| (1)-(5) | | | | nok | program- | | Főprogram | +--------+ | (4) | szegmens | | (1) | |Verem(2)| +----------+ | +-----------+ +--------+ +----------------+ | +---------------------+ | Szimbólumtábla | | |Dinamikus változók(3)| | (5) | | +---------------------+ +----------------+ / .-----------------------------------------------. HARDVER MEGOLDÁS Max +-Fizikai tár-+ Változatlan marad | | +---------------+ | 2. szegmens | | [3]| |=============| +-----+ . | [2] v [5]d | 5. szegmens | | CPU |->|p|d| +->|f|d|------>| -*-Végcím - | +-----+ | | | | | Eltolás | p|Pointer | | | d|(Displace-| | +-9-+ | | [4]f | | ment) | |[1]+-8-+ | +--------->+==*=Alapcím==| | +-7-+ | A fizikai | | | +-6-+ | szegmens címe| 4. szegmens | Index +-->+-5-+---+ |=============| (Pointer) +-4-+ Címtranszformáció| 3. szegmens | +-3-+ [1]-[5] lépés |=============| +-2-+ | | +-1-+ | 1. szegmens | Szegmenstáblázat 0 +-------------+ / | | | | | | | \

3.6. ábra. Szegmensek

3.4.3. Központi egység elosztás A központi egység ütemezése a számítógép-rendszer legfontosabb erőforrásával való gazdálkodást jelent. A központi egység ütemezése a folyamatok vezérlésére vonatkozik. Első közelítésben egy folyamat új, aktív, várakozó, holtponti vagy befejezett állapotban lehet. *------* *-------* *----------* ( ÚJ ) =======> ( AKTÍV ) =======> ( BEFEJEZETT ) *------* *-------* *----------* ^ | | *---------* | | +---> ( HOLTPONTI ) | | *---------* | v *-------* (VÁRAKOZÓ ) *-------* 3.7. ábra. Folyamatállapot diagram Az ütemezést a folyamatok különböző sorokba való rendezésével és a megfelelő sorkezelő algoritmusok segítségével oldják meg. Az aktív és várakozó folyamatok az ún. készenléti sorba kerülnek. Ezenkívül minden B/K egységhez tartozik egy sor, amely az egységre váró folyamatokra mutat. Az ütemezés két, esetleg három szinten megy végbe. A magas szintű ütemező a külső tárolón várakozó munkákból kiválasztja a készenléti sorba kerülőket, az alacsony szintű (központi egység) ütemező pedig ebből a sorból aktivizál egy-egy folyamatot. A magas szintű, és az ún. közbenső ütemező célja megfelelő, vagyis a rendszert egyenletesen terhelő munkakeverék összeállítása, amelyből azután a központi egység (alacsony szintű) ütemezője hatékonyan ellátja munkával a rendszert. Erre sokféle algoritmus létezik: * * * *

előbb jött -- előbb fut, a legrövidebb előnyben, prioritás alapú vezérlés, körbenjárásos üzem.

Az algoritmusok a 9. fejezetben megtalálhatók. Amint az várható, nincs optimális központiegységütemező, amely tetszőleges munkakeverékre egyformán jó eredményt adna. A központi egységhez hasonlóan a külső egységek ütemezése is sorok alapján történik. Az ütemezésnek elsősorban a nagy kapacitású, mozgófejes mágneslemezeknél van nagy jelentősége. Több algoritmus ismeretes, közös vonásuk, hogy a működés során igyekeznek a fejmozgatást minimalizálni, mert ez a legidőigényesebb tevékenység. A rögzített fejes lemezek, illetve mágnesdobok ütemezésénél fejmozgás nincs, itt az ún. holt időt (ami alatt a lemez kívánt pontja az olvasófej alá fordul) kell minimalizálni. 3.4.4. A holtpontok problémája A holtpont elkerülése meglehetősen bonyolult algoritmust igényel. Első lépésben meg kell keresni azon feltételeket, amelyek együttes teljesülése szükséges a holtpont beállásához. Amint ezt a 8. fejezetben látni fogjuk, egy négy feltételből álló, kissé redundáns szabályhalmaz elegendő erre a célra. Ezután a holtpontokat két alapvető stratégia szerint kezelhetjük: a szükséges feltételek ellenőrzött elkerülésével biztosítjuk, hogy holtpont ne álljon be; vagy csak a holtpont esetleges bekövetkezését figyeljük, és ebből megpróbáljuk a rendszert feléleszteni. A párhuzamos folyamatok kezelésének alapproblémája: mikor lehet egy programban két utasítást

párhuzamosan végrehajtani úgy, hogy a program a végrehajtási sorrendtől függetlenül azonos eredményeket produkáljon? A gyakorlati megoldások a programozási nyelvek körében keresendők. A két legismertebb megoldás a "fork -- join", illetve a "parbegin -- parend" utasítások használata (ld. 12. fejezet). Ha a párhuzamos folyamatok programozása megoldott, felmerül a folyamatok holtpontjának problémája, amit "kölcsönös kizárás"-nak neveznek, és a párhuzamos folyamatok szinkronizációjával kerülhető el, amelynek eszközei a Dijkstra által bevezetett szemaforok lehetnek. 3.4.5. Védelmi kérdések A védelmi kérdések az operációs rendszeren belül azért játszanak fontos szerepet, mert a sok, egymástól függetlenül vagy együttműködve lezajló folyamat mindegyikét meg kell védeni a többiek nemkívánatos mellékhatásától. E célra több mechanizmus szolgál (ld. 11. fejezet), amelyek azt igyekeznek lehetővé tenni, hogy az állományokat, a társzegmenseket, a központi egységet és egyéb erőforrásokat csak olyan folyamatok kezelhessék, melyek az operációs rendszertől kaptak erre megfelelő "felhatalmazást". Például az állományok rendszerében a hozzáférést úgy kell szabályozni, hogy az állomány tulajdonosának a joga legyen azt előírni, hogy ki férhet hozzá az állományaihoz. A rendszer órája pedig azt hivatott biztosítani, hogy egyetlen folyamat se sajátíthassa ki korlátlan időre a központi egységet.

3.5. Kötegelt (batch) rendszerek A kötegelt elnevezés tulajdonképpen -- az egyfelhasználós rendszerek korai időszakából származó üzemmódot figyelembe véve -- a számítógépes rendszerhez való hozzáférés módjából ered. Az operációs rendszer egymástól független munkák végrehajtására vonatkozó igényeket fogad, s ezekből olyan kötegeket (angol nevük batch) hoz létre, melyeket azután a körülményeknek megfelelő időpontban hajt végre. Az igények közlésére kezdetben lyukkártyákat (3.8. ábra), később más eszközöket (terminálokat, távközlési vonalakat stb.) használtak. ------------------------------------+ /$END . . . . . . . . . . . . . . . .| / A PROGRAM ADATAI /|| -------------------------------------+ || /$RUN | || --------------------------------------+ | |+ /$LOAD | | + ---------------------------------------+ | |/ / . . . . A PROGRAM . . . . . . . . . ./| |-+ / . . . . FORRÁSKÓDJA . . . . . . . . ./ | | ---------------------------------------+ |-+ /$FTN | | | | + --------------------------------------+ | / /$JOB | |/ | |--+ | | | | +--------------------------------------+ 3.8. ábra. Kötegelt rendszert vezérlő kártyacsomag

A kötegelt rendszerek alapvető sajátsága, hogy a programozókat elválasztja a géptől -- általában a géptermekből is kitiltották őket -- a számítógépes rendszer kezelését pedig az e célra kiképzett gépkezelők (operátorok) végzik. A programozó dolga az, hogy egy futás eredményeiből minél gyorsabban előállítsa a következő gépi futás anyagát, hiszen elsődleges cél a számítógéprendszer folyamatos leterhelése. Ezt már az egyfelhasználós rendszereknél is meg tudták közelíteni, de csak a multiprogramozás elterjedése, valamint egyes tevékenységek párhuzamossá tétele hozott igazi eredményt. A programozó által összeállított köteg tulajdonképpen "vezérlőnyelven" (munkavezérlő nyelv) írott program, amely a végrehajtásához szükséges adatokat vagy az ezek tárolási helyét megadó utalásokat is tartalmazza. A kötegelt rendszerek vezérlőnyelve horizontális jellegű, mert kevés számú parancsból építkezik (vertikális struktúra), de az egyes parancsok igen bonyolultan paraméterezhetők (horizontális struktúra). A kötegelt rendszerek fejlettségi szintjét elég jól jellemzi az erőforrás-kezelés automatizálásának, és dinamikusságának mértéke (ld. 8. fejezet), s ezen belül különösen fontos a tárkezelés (ld. 10. fejezet). A fix, majd a változó partíciók használata után a virtuális címzés jelentette a fejlődést. A kevésbé fejlett rendszerek túl hosszú ideig lekötik a folyamatok számára az általuk igényelt erőforrásokat, ami rontja az erőforrások kihasználtságát, de javíthatja az átbocsátó képességet az alacsonyabb rendszeradminisztrációs terhelés miatt. A kötegelt rendszerek azonban a fejlesztők minden igyekezete ellenére sem tudták kielégíteni a változó felhasználói igényeket és ezen még a nagy rendszerekhez illesztett telekommunikációs lehetőségek sem segítettek. Egyes területek, elsősorban az új szoftver rendszerek fejlesztései nem tudták elviselni azt a két forduló közötti néhány órás várakozást sem, amit csak a jól felszerelt és jól szervezett számítóközpontok biztosítottak. A fejlesztők teljesítményét és munkájuk minőségét egyaránt javítja, ha a számítógéprendszerrel állandó közvetlen kapcsolatban (angolul: on-line) vannak. Ilyenkor ugyan a hardver nagyrészt tétlenkedik, de az ebből származó anyagi veszteséget azonban meghaladja a fejlesztett termék jobb minőségéből és rövidebb fejlesztési idejéből származtatható nyereség. Amikor a hardverárak ezt már lehetővé tették -- nem véletlenül először a kisgépek körében --, megjelentek a különböző interaktív rendszerek, illetve a meglévőket on-line hozzáféréssel igyekeztek kiegészíteni. Ilyen bővítést hajtott végre például az IBM is a TSO (Timesharing Option) alrendszerének bevezetésével. Ma a nagygépes operációs rendszerekre általában a kötegelt -- interaktív vegyes üzemmód a jellemző. Az üzemszerű, ismétlődő feldolgozások kötegelt módon futnak, a fejlesztés pedig jórészt on-line formában zajlik.

3.6. Időosztásos rendszerek A kötegelt rendszerek számára is sokat jelentett a kizárólag soros hozzáférést biztosító lyukkártya és mágnesszalag után a közvetlen elérést nyújtó lemezek elterjedése. A kötegelést az operációs rendszer végezhette, hiszen biztosított volt a munkákhoz való tetszőleges sorrendű hozzáférés. Ennek dacára a kötegelt rendszerek két alapvető hátránya megmaradt: * Nincs interakció a programozó és a rendszer között a munka végrehajtása közben. Mivel sok esetben egy feladat következő lépése az előzőtől függ (egy program futása pl. a fordítás sikerétől), a programozónak minden eshetőségről előre intézkednie kell, ami többletmunka és gyakran igen bonyolult. * A programok hibáit statikusan, tárkivonatokból (angolul dump) kell megtalálni, ami ugyan inspirálhatja a fegyelmezett, módszeres programírást és tesztelést, de mindenképpen csökkenti a fejlesztők teljesítményét.

Ezeken és egyéb problémákon igyekeznek segíteni az interaktív rendszerek, ahol a felhasználó állandó és folyamatos kapcsolatban áll a programjával annak írása és végrehajtása során. A rendszer általában billentyűzetből és képernyőből álló terminálon át bevitt parancsok segítségével vezérelhető. A parancsok azonnal végrehajtódnak, és az eredménytől függően a programozó "online" dönt a következő lépésről. A hangsúly a gyors válaszon van. Az on-line rendszerek vezérlőnyelvét inkább parancsnyelvnek nevezik, mert kiadásuk után a rendszer rögtön reagál. Ez olyan, mintha csak a parancsoknak engedelmeskedne. Az on-line parancsnyelvek abban különböznek a kötegelt rendszerek vezérlőnyelvétől, hogy vertikális jellegűek. Sok parancsból építkeznek (vertikális struktúra), és az egyes parancsok paraméterezése általában egyszerű (horizontális struktúra). (Lehet, hogy a VAX/VMS és a TSO ismerői egy kicsit ingatják a fejüket. Sajnos, mindkét vezérlőnyelv korai, kötegelt vezérlőnyelvi beidegzések nyomait viseli magán. A "tiszta" példa a UNIX, illetve a még frissebb MS--DOS. – Azóta a UNIX is elhorizontálosodott!! – ZSP, 2001). Az időosztásos (angolul: time-sharing) operációs rendszer célja, hogy a számítógéprendszer interaktív használatát több felhasználó számára párhuzamosan (és ezért csökkentett költséggel) lehetővé tegye. Ennek érdekében az operációs rendszer a központi egység megfelelő ütemezésével és multiprogramozás alkalmazásával a gép idejét több felhasználó között osztja meg. Különösen programfejlesztésnél igaz, hogy az éppen aktív folyamat egy rövid időn belül befejeződik, vagy B/ K műveletet igényel. Mivel az interaktív adatbevitel gyakran billentyűzetről folyik, ami a gép szempontjából igen lassú, a rendszer gyakran váltogathatja a felhasználók kiszolgálását, mégis mindenki úgy érzi, hogy egyedül dolgozik. Az időosztásos rendszerek az erőforrások igazságos elosztása érdekében védekeznek az ellen, hogy egy folyamat (véletlenül vagy szándékosan) korlátlan ideig aktív maradhasson. Erre a célra általában a gép órájának megszakítását használják olymódon, hogy az órajel valamilyen többszörösével kifejezhető "időszelet" elmúltával másik folyamatra kapcsolnak át. Az időszelet nagysága függhet az alkalmazási környezettől és a pillanatnyi terheléstől is. Az időosztás elve már 1960-ban ismert volt, de a szoftver bonyolultsága és a technikai színvonal miatt elterjedni még nem tudott. Általános gyakorlattá válása mintegy tíz évig váratott magára, azóta viszont népszerűsége egyre növekszik. A kötegelt rendszerek időosztásos alrendszerrel való bővítése mellett természetesen az időosztásos rendszerekben is gyakran gondoskodnak kötegelt üzemmódról a rutinszerűen ismétlődő munkák végrehajtásának egyszerűsítése érdekében. (Ilyenek például a PDP 11-es RSX-ben végrehajtható ".CMD" kiterjesztésű állományok, amelynek ötletét később átvették az egyfelhasználós, egyáramú, interaktív mikrogépes operációs rendszerek -CP/M, MS-DOS -- is. Az RSX-ben speciális kötegelt vezérlő alrendszert (Batch and Queue Manager) lehet használni a háttérben futó alkalmazások kezelésére. Amíg ezek a háttérmunkák az alkalmazó segédlete nélkül függetlenül futnak, addig az alkalmazó a terminálon (tehát az előtérben) interaktív üzemmódban dolgozhat. Az első közismertté vált időosztásos rendszert, a MULTICS-ot 1965 táján, egy amerikai egyetemen fejlesztették ki a General Electric GE--645 típusú nagygépére PL/1 nyelven. A fejlődés következő állomása a kisgépes kategória volt. Itt az időosztásos rendszerek "prototípusa" a UNIX, sok eredeti megoldás mellett jócskán merített a MULTICS ötleteiből és más, korábbi DEC operációs rendszerekből is. A Bell Laboratóriumban kidolgozott rendszer első elterjedt változata eredetileg a DEC PDP--11 családjára készült. Azóta a UNIX-szerű operációs rendszerek halmaza nagyon kibővült; a mikrogépek megjelenésekor pedig a CP/M, MP/M majd az MS--DOS egyaránt sokat kölcsönzött a UNIX-tól. A szintén időosztásos OS/2 sajnos újabb ötleteket nem vett át, programozói interfésze pedig már merész, új utakon jár (magasszintű-nyelv orientált szolgáltatáshívások), bár a futás alatti szubrutinkönyvtárát a UNIX bináris programkönyvtári elvének továbbfejlesztéseként vehetjük.

3.7. Valós idejű rendszerek Egyes, speciális feladatok gépesítése támasztotta azokat az igényeket, amelyek a valós idejű operációs rendszerek kialakulásához vezettek. Ezek a rendszerek tulajdonképpen, egyedi alkalmazások vezérlő mechanizmusainak tekinthetők. Az adatok a gépbe érzékelőkről (általában mérőműszerekről) érkeznek. Az operációs rendszer feladata az adatok elemzése és -- szükség esetén -- olyan vezérlő mechanizmusok aktivizálása, melyek befolyásolhatják az érzékelők által mért értékeket. Tipikus valós idejű alkalmazás például a forgalmi rendszerek (közlekedési lámpák) vezérlése, ipari folyamatok, tudományos kísérletek irányítása stb. A valós idejű operációs rendszerek közös jellemzője, hogy a munkák elvégzését szigorú időkorlát köti. Rendszerhibával egyenértékű, ha egy munka nem hajtódik végre a hozzárendelt időkorláton belül. Amíg a kötegelt operációs rendszereknél lényegtelen, az időosztásos rendszereknél fontos, de nem meghatározó, addig a valós idejű rendszereknél az időkorlát döntő jelentőségű. A valós idejű környzetek további fontos tulajdonsága az eseményvezérelt (angolul: event driven) jelleg. Az operációs rendszer nem vezérli a feldolgozást, hanem fogadja és teljesíti a kérelmeket. A kérelmek teljesítését biztosító programokat elterjedt DEC szóhasználattal taszkoknak hívják, de ezek megfelelnek az általunk korábban definiált folyamat fogalmának (programok működés közben). Bár a valós idejű rendszerek logikája az emberi beavatkozással kapcsolatos követelményeket minimalizálni igyekszik, ezek teljesen mégsem nélkülözhetők. Különösen a rendszer paramétereinek beállításakor, az értékhatárok túllépésénél vagy hibás működés esetén van emberi beavatkozásra szükség. A hangsúly nem az erőforrások optimális kihasználásán, hanem a biztonságos üzemen van. A teljesítményparamétereket úgy kell választani, hogy az idő korlátok csúcsterhelés esetén is tarthatók legyenek. A méretezést tehát a csúcsterhelésre végzik. Ennek érdekében gyakori a hardverredundancia és az, hogy a szabvány processzorok egy speciális, módosított változatát alkalmazzák. A teljes alkalmazási rendszerben a számítógépes alrendszer néha alig vehető észre, a programokat általában máshol fejlesztik, ide gyakran már csak megváltoztathatatlan végrehajtható formában, ROM-ba égetve kerülnek. A valós idejű alkalmazások szoftvere a szokásosnál több szempontból is bonyolultabb. Egyrészt az egész programrendszernek -- legalább gyakorlatilag -- hibamentesnek kell lennie, másrészt a programok belövését nem lehet a megszokott módon elvégezni, mivel a próbához szimulálni kell a teljes környezetet az összes bekövetkezhető eseménnyel együtt. Erre azért van szükség, mert hiába működik egy program hibátlanul egy laboratóriumi környezetben, arról is meg kell győződni, hogy minden folyamat akkor is időkorlátján belül marad, ha a rendszer teljes terhelés mellett üzemel.

3.8. Többprocesszoros rendszerek Az igazi többprocesszoros operációs rendszerek felügyelete alatt egynél több központi egység működik, melyek osztoznak a táron és a perifériákon. Az ilyen rendszer nyilvánvaló előnye a nagyobb teljesítmény és a biztonság lenne. Jelenleg azonban sajnos a teljesen általános többprocesszoros operációs rendszerek még váratnak magukra. A meglevő megoldások két fő irányt követnek: * Egy központi processzor több, alárendelt gépet vezérel, amelyek csak korlátozott tevékenységre képesek (master/slave kapcsolat); *

Számítógép-hálózatok, melyekben több számítógéprendszer áll kapcsolatban

egymással üzenetek és adatállományok cseréje útján. Minden gép -- a többitől függetlenül -- a saját operációs rendszerével működik. Az első megoldást már rég alkalmazzák, például úgy, hogy a központi géptől távol elhelyezett kis processzorokat csak a terminálok vezérlésére, és a munkák központba küldésére használnak, ahol azok kötegelt üzemmódban végrehajtódnak. E kihelyezett gépeket RJE (Remote Job Entry) állomásoknak nevezik. Időosztásos rendszereknél is szokásos, hogy egy nagy teljesítményű központi gép köré több kisebb, ún. front-end processzort telepítenek, amelyek csak a terminálokon folyó információ be- és kivitelét bonyolítják. Viszont back-end processzorokat is használnak speciális, bonyolult algoritmusok gyors kiszámítására (ilyenek pl. az INTEL 8086/80?86-os család aritmetikai koprocesszorai, a harci eszközök becsapódási pályáját gyorsan kiszámító berendezések, a mátrixprocesszorok, vagy a sejtszámítógépek stb.).

3.9. Hálózatok és elosztott rendszerek A számítógép-hálózatokban önálló számítógépes rendszerek vesznek részt, melyeket különböző adatátviteli vonalak kapcsolnak össze: közvetlen adatbuszok, telefonvonalak stb. A hálózat célja a feladatok ésszerű megosztása a tagok között, ami nyilvánvaló kölcsönös előnyökkel jár. Erre utal az elosztott vagy osztott (angolul: distributed) elnevezés. Egy számítógép-hálózatot azonban csak akkor mondunk elosztott rendszernek, ha az összekapcsolás nem véletlenszerűen, hanem előre meghatározott cél alapján történik. Az elosztott rendszerben résztvevő számítógép-erőforrások méretüket, teljesítményüket és funkciójukat tekintve igen változatosak lehetnek: mikroprocesszorok, terminálok, kisgépek, nagy, univerzális számítógépek stb. Az egyöntetűség kedvéért ezekre, mint a hálózat csomópontjaira vagy egyszerűen csak mint gépekre hivatkozunk majd. Elosztott rendszerek létrehozását négy fő cél indokolja: az erőforrások megosztása, a sebességnövelés, a megbízhatóság megalapozása és a kommunikáció. Mivel ezek a célok minden elosztott rendszerre vonatkoznak, a tárgyalást velük kezdjük. * Erőforrás-megosztás: Mivel sok, különböző lehetőségekkel felszerelt csomópont kapcsolódik össze, az egyik csomóponton használni lehet olyan erőforrásokat, amelyek helyileg egy másik csomóponton vannak. Például az A gép használhatja a B géphez kapcsolt lézernyomtatót, miközben B dolgozhat az A-ban tárolt adatállományból. * Sebesség növelés: Ha egy nagy volumenű számítási feladatot konkurens módon futtatható részekre lehet bontani, az egyes részek szétoszthatók a csomópontok között és párhuzamosan hajthatók végre. Ezen túlmenően, a túlterhelt csomópontokról a munka egy része más gépekre irányítható (load sharing). * Megbízhatóság: Ha az elosztott rendszer egyik csomópontjában géphiba lép fel, a többi csomópont elvileg működőképes marad. Ha a rendszer több nagy, önálló számítógépből áll, az egyik kiesése nem nagyon zavarhatja a többit. Ha viszont a hálózat sok kis gépből épül fel, melyek mindegyike egy speciális funkciót lát el (pl. állomány kezelés, terminál B/K), egy gép hibája megbéníthatja az egész rendszert. Általában igaz, hogy ha a rendszerbe elegendő redundanciát építettek (mind a hardver, mind az adatok szempont-

jából), egy vagy néhány gép kiesését a hálózat jól elviseli. Különösen bonyolult kérdéskör a hiba automatikus észlelése, áttérés a sérült rendszer üzemére, majd -- a hiba elhárítása után -- visszatérés a normális működésre. * Kommunikáció: Az összekötött csomópontok közötti adatcserét általában a postahivatalok mintájára szervezik meg, és "elektronikus postá"-nak hívják. A hálózat minden felhasználója kap egy "postaládát", amelyhez a csomóponton egyedi név tartozik. Postát bárki küldhet bárkinek a csomóponton belül vagy más csomópontra is. A cím a postaláda és a csomópont nevéből tevődik össze. Az elküldött postákat az operációs rendszer a címzett postaládájában tárolja. Elolvasás után a címzett intézkedhet az üzenet törléséről, tárolásáról, esetleg további címekre való továbbításáról vagy a válaszról. Az elosztott rendszerek csomópontjait többféleképpen lehet összekapcsolni. A különböző konfigurációk kialakításánál elsősorban három fő szempontot szoktak figyelembe venni: * Létesítési költség: Mennyire költséges az egyes csomópontok közötti kapcsolat kiépítése? * Kommunikációs költség: Mennyi ideig tart egy üzenet két csomópont közötti átvitele? * Megbízhatóság: Ha hiba lép fel egy csomópontban vagy egy összekötő vonalban, a rendszer maradék csomópontjai még kapcsolatban maradnak-e egymással? A különböző konfigurációkat gráfokkal ábrázolják, melyek csúcsai a csomópontok, élei pedig a direkt kapcsolatokat reprezentálják. A teljes kapcsolású hálózatban az összes csomópont között közvetlen kapcsolat van. A létesítési költségek nagyok, de a rendszer igen megbízható, és a kommunikációs költségek minimálisak. -{C}----|\ \ / | \ \ / | \ \ / | \ \ {B}----|---------{D} \ \ | \ / | \ ----|----- \/ | \ | \/\ | \ | /\ \ | \ | --- \ \ | \ | / \ \| {A}--------{E} /

3.9. ábra. Teljes kapcsolású hálózat

-{C}----\ \ / \ \ / \ \ / \ \ {B}--------------{D} \ \ | \ \ | \ \ | \ \ | \ \ | \ \| {A} {E} /

3.10. ábra. Részleges kapcsolású hálózat

A részleges kapcsolású hálózatban több direkt kapcsolat hiányzik. Az üzeneteket esetleg közbenső csomópontokon keresztül kell továbbítani. A létesítési költség kisebb, de az üzemelés lassúbb és a megbízhatóság is csökken. A részleges kapcsolású hálózatok speciális esete a csillag- és a gyűrűs hálózat. Mindkettő létesítési költsége a csomópontok számával lineárisan nő. A csillaghálózatban egy központi géphez kapcsolódik a többi csomópont (3.11. ábra). Az üzenetek átvitele egyszerű, de gyakran lassú a központi gép túlterhelése miatt. Ezért ez gyakran kizárólag üzenetkapcsolással foglalkozik. A gyűrűs hálózatban mindegyik csomópont pontosan két másikkal van közvetlen kapcsolatban

(3.12. ábra). Ha a gyűrűben az üzeneteket csak egy irányba lehet küldeni, akkor a kommunikációs költség igen magas lehet; ellenben ha minden csomópont üzenhet mindkét szomszédjának, akkor az üzenetátvitel felgyorsul. {B} | | | | | {H}-------{A}--------{F} / \ / \ / \ / \ / \ {X} {D} 3.11. ábra. Csillaghálózat {D}----{E} \

/ /

\

/

\

/ {C} | | | {B} \

\ {F} | | | {G} / \

/ \

/ \

/ {A}----{H} a)

{D}----{E} / |\ \ / | \ \ / | \ \ / | \ \ {C} | ------{F} | | /| | | / | | | /--- | {B} | / {G} \ | / / \ | / / \ | / / \ |/ / {A}----{H} b)

3.12. ábra. Gyűrűs hálózatok. a) Egyszeres, b) Többszörös Külön meg kell említeni a közös információs busszal rendelkező hálózatokat, ahol a csomópontok közös vonalon át kommunikálnak. A telepítési költség a csomópontok számával arányos, a kommunikáció meglehetősen olcsó, de a busz átbocsátó képessége könnyen szűk keresztmetszetté válhat. A rendszer működését egy-egy csomópont hibája nem zavarja, azonban a közös vonal megbízhatósága létfontosságú. {A} {B} {C} {D} {E} {F} {G} {H} | | | | | | | | | | | | | | | | +-------+--------+-----+------+-----+-------+----+ 3.13. ábra. Busszal rendelkező hálózat

A hálózati rendszereket két nagy csoportra oszthatjuk: számítógép-hálózatok és helyi hálózatok. Bár a felosztás elsősorban a csomópontok földrajzi eloszlására vonatkozik, az eltérő igények nyomot hagytak az operációs rendszerek felépítésén is. A számítógép hálózatok több, önálló gépből állnak, melyek nagy területen (pl. egy ország vagy földrész) szóródnak szét, a helyi hálózatok pedig csak egy épületben vagy épületcsoportban telepített processzorokból állnak.

3.10. Mintapéldák A régi egyfelhasználós rendszerek csak történelmi érdekességgel bírnak. A világszínvonalat már az 50-es években is az IBM képviselte, például a 7094-es rendszerével. Magyarországon az első gépek csak 1960 körül jelentek meg igen változatos összetételben. A többi között angol (Elliott 803), francia (Bull Gamma), szovjet (M3, Ural, Minszk--22) és dán (GIER) gépekkel felszerelt, egyfelhasználós üzemben működő számítóközpontok üzemeltek. A kötegelt rendszerek között klasszikusnak számít -- mint azt már a 2. fejezetben is elemeztük, -- az IBM DOS, illetve OS/360. Ezek sajnos a felhasználók összes lehetséges igényét ki akarták elégíteni, ezért azután jóformán sehol nem adtak különösebben jó megoldást. Az állományrendszerben különböző állománytípus tartozott a fix és változó hosszúságú rekordokhoz, valamint a blokkolt és nem blokkolt állományokhoz. Az állományokat folyamatos címek szerint tárolták, ezért a felhasználónak előre meg kellett becsülni az állomány hosszát. Az igen horizontális munkavezérlő nyelv (JCL) az összes lehetőségre paraméterekkel igyekezett felkészülni, ezért az átlagos felhasználó számára jóformán érthetetlen volt. (Az emiatt fellépő tipikus JCL használat: ellesünk egy-egy vájt fülűtől egy "jó jobot", és azt használjuk nyakra főre, ha jó, ha nem. A nyelv lehetőségeiről pedig lemondunk. De lemondhat az operációs rendszer is arról, hogy nem fogunk pazarolni az erőforrásaival! A felhasználó visszavág a "birodalomnak"!) A tárkezelés alapvető ellentmondásba került az architektúrával: a címzéshez bázisregiszter lehetett használni, de a programok módosíthatták a bázisregisztert, ezért a központi egység abszolút címeket generált. Ez lehetetlenné tette a programok dinamikus áthelyezését, a betöltéstől kezdve a program helyhez kötötté vált. Az OS/MFT fix, az OS/MVT pedig változó partíciókkal dolgozik. Az IBM/370 architektúra virtuális tárral jelent meg, amely szegmentált-lapozott virtuális tárat biztosított. Az OS új változatai azonban ezt a tárat különböző módon kezelték. Az OS/VS1 egyetlen nagy virtuális címtartományt hozott létre, amelyben az OS/MFT-t futtatta. Ebben az operációs rendszer is lapozva futott, akárcsak a felhasználói programok. Az OS/VS2 először az OS/MVT-t futtatta egyetlen virtuális tárban, majd az MVS-nek nevezett második változat (ami még mindig csak egy kötegelt rendszer) adta meg végre minden felhasználónak a saját virtuális tárát. Minden kritika ellenére tény, hogy nagygépeken legnagyobb számban valószínűleg ma is az OS operációs rendszer működik a világon. A többi kötegelt rendszer közül a következőket érdemes kiemelni: Az Atlas operációs rendszert a Manchesteri Egyetemen tervezték az 50-es és 60-as évek fordulóján. Több szép (azóta már közkinccsé vált) technikai megoldást tartalmazott, de tárkezelése különösen előremutató volt. Az akkor még ritka és drága ferrittárból csupán egy kis (16 Kszó), gyors tárat alkalmazott, és egy 98 Kszavas dobbal igen hatékony lapkezelő algoritmust valósított meg. A hardver egy 48 bit szóhosszúságú Ferranti gép volt. A THE operációs rendszer, amely egy EL X8 nevű holland gépen működött (32 K 27 bites szó), Dijkstra és társai nevéhez fűződik. A rendszer szép szoftverstruktúrájával tűnt ki, ami különösen a konkurens folyamatok szemaforokkal való szinkronizációjában és holtpont elkerülő algoritmusában

öltött testet. A THE egyetlen magas szintű programozási nyelve az ALGOL volt. Az időosztásos rendszerek írott történetét általában a MULTICS-al kezdik, pedig ez már egy korábbi, CTSS-nek hívott rendszer továbbfejlesztése volt a 70-es évek elején. A helyszín az MIT (Massachusetts Institute of Technology), a hardver egy GE 645-ös gép, szegmentált lapkezeléses tárral. A MULTICS jóformán teljesen PL/1-ben készült, a forrásszöveg mintegy 300.000 sort tett ki. Több processzoros környezetre is kibővítették, hogy a felhasználók kiszolgálása a központi egység karbantartása alatt is biztosítható legyen. A legsikeresebb időosztásos operációs rendszer a Bell Laboratóriumban PDP gépekre kifejlesztett UNIX, amely sok tekintetben a Multics barátságosabb kisgépes változata. A fejlesztők egyike (D. Ritchie) korábban a MULTICS témán dolgozott. A másik kulcsember, K. Thompson, a PDP gépek elismert szakértője volt. A UNIX tulajdonképpen csak harmadik változatában került a nagyobb nyilvánosság elé, miután a szerzők az általuk erre a célra kidolgozott és C-nek nevezett rendszerprogramozási nyelven újraírták, elsősorban az átvihetőség javítása céljából. Ezzel megnyílt az út a nagyobb PDP modellek, a 11/45, 11/70, majd a VAX-ok felé. A UNIX először az egyetemeken terjedt, és csak 1976-ban került ki szélesebb körbe a Bell Laboratóriumból. A UNIX sok, azóta is korszerűnek számító megoldást tartalmaz. A felhasználóval egyszerű nyelvű, és könnyen cserélhető parancsértelmező (Shell) tart kapcsolatot. Adatkezelése a több szintű faszerkezetet mutató állományrendszeren alapul, amely minden felhasználónak saját alkönyvtár létesítését teszi lehetővé. Az állományokat védeni lehet írás, olvasás és végrehajtás, a katalógusokat írás, olvasás és keresés ellen. Minden adatállomány egyszerűen karakterek sorozata. A perifériák kezelése annyira egységes, amennyire ez megoldható. A UNIX a párhuzamos folyamatok általános kezelését teszi lehetővé. Minden folyamat könnyen hoz létre új folyamatokat. A virtuális tárat a rendszer lapkezeléssel valósítja meg az ún. igény szerinti lapváltás (angolul: demand paging) módszerével. A UNIX-ot programozók tervezték programozók számára, ezért erősen interaktív, és elsősorban a programfejlesztők igényeit igyekszik kielégíteni. A UNIX, bár a minigépekre született, jól megállja a helyét személyi számítógépes operációs rendszernek is. A UNIX tervezői saját igényeik szerint dolgoztak, az algoritmusokat egyszerűségük és nem hatékonyságuk szerint választották. A jól strukturált felépítés sok módosítást motivált, és sok utánzatot ihletett. Ezek közül a professzionális személyi számítógépeken legismertebb a XENIX. A PDP gépek másik -- inkább csak a családon belül népszerű -- operációs rendszere az RSX, melyet VMS néven fejlesztettek tovább a VAX-ra. Ezek is interaktív parancsnyelvű rendszerek, és mindent tudnak, ami egy időosztásos rendszertől elvárható. Az időosztásos operációs rendszerek területéről természetesen az IBM sem szorulhatott ki. Már a 360/67-es (virtuális tárral rendelkező) modellre elindult 1968 körül a TSS/360 fejlesztése. A feladat azonban túl nagynak bizonyult és a késés miatt kiadták az OS/360 egy időosztásos bővítését, a TSO-t, majd az eredetileg egyfelhasználós CMS-t (Cambridge Monitor System). A TSS végül 1973 táján készült el, de megbukott, mivel túl nagy volt és lassú. Amit egy kötegelt rendszernél még elviseltek a felhasználók, az időosztásos rendszernél már nem volt eladható. Azt már korábban említettük, hogy a nagygépek univerzális alkalmazási filozófiája is aláásta a külön időosztásos rendszer létjogosultságát, mert kényelmetlen, és gazdaságtalan állandóan váltogatni a gépen az operációs rendszereket. Az IBM rendszerekben az időosztást ma is főleg a TSO vagy a CMS segítségével valósítják meg.

3.11. Gyakorlatok 3.11.1.

Hogyan jellemezné a következő típusú operációs rendszereket? a) kötegelt b) valósidejű c) időosztásos

3.11.2.

Mi a spooling?

3.11.3.

Mit jelent a kötegelés?

3.11.4.

Mi a multiprogramozás lényege?

3.11.5.

Mit nevezünk swappingnak?

3.11.6.

Melyek a particionált tárkezelés alapesetei?

3.11.7.

Vesse össze a program és a folyamat fogalmát!

3.11.8.

Mi a lapkezelés és a szegmentálás?

3.11.9.

Mit jelent a központi egység ütemezése?

3.11.10.

Hányféle ütemező használatos?

3.11.11.

Mi a virtuális tár és hogyan kezelik az operációs rendszerek?

3.11.12.

Mi a holtpont helyzet és hogy oldhatók meg az ezzel kapcsolatos problémák?

3.11.13.

Ismertesse a párhuzamos folyamatok problémakörét!

3.11.14.

Mi az elosztott rendszerek alapvető célja?

3. Milyen fontosabb hálózatkonfigurációkat ismer?

OS04V06.RTF,2ki.4.16,ZSP

4. MŰVELETI FÁZISOK

Ebben a fejezetben megvizsgáljuk, hogyan oldható meg egy feladat a számítógépes rendszerben, és hogyan viselkedik ezalatt az operációs rendszer. Meghatározzuk a feladat egységét, a munkát, majd elemezzük a jellemző műveleti fázisokat. Megjegyezzük, hogy egy-egy konkrét munka kapcsán nem minden műveleti fázis merül fel.

4.1. A feladat egysége: a munka Az operációs rendszereket alaposan felkészítik arra, hogy szét tudják választani az egyes felhasználók feladatait. Sőt arra is, hogy az egyes felhasználóknak is lehetővé tegyék a különálló feladatok elhatárolását, hogy azok ne keveredhessenek össze. Azt a feladategységet, amelyet a felhasználó különállóan akar kezelni, munkának (angol szóval: job) nevezzük. A kötegelt operációs rendszerekben a korábban már tárgyalt munkavezérlő nyelvek alkalmasak arra, hogy kijelöljék egy munka elejét és végét, valamint a munka végrehajtási lépéseit. Minthogy a korai számítógépeken a kötegelés széleskörűen elterjedt, a számítógépes rendszerekben a munka egységének fogalmát a kötegelt rendszerekben kialakult gyakorlatnak megfelelően alakították ki. A munkát az operációs rendszernek valahogy azonosítania kell. A kötegelt rendszerekben ez a munka elejét jelző munkavezérlő utasításban megadott névvel (job-név, munkanév) történik. Az interaktív környezetben a felhasználók szétválasztását (elvileg) automatikusan biztosítja, hogy minden terminálon más felhasználó jelentkezik be. Így a felhasználó azonosítható azzal a terminállal, amelyen bejelentkezett. Ez viszont olyan megkötéssel járna, hogy egy felhasználó több terminálon nem jelentkezhet be. Emiatt az interaktív rendszerekben a felhasználók azonosítása két adattal történik: egyrészt a terminálszámmal, másrészt a bejelentkezési-, más néven számlázási (account) névvel, amelyet a számítóközpont üzemeltető személyzete ad a felhasználónak akkor, amikor gépidőt vásárol. Az interaktív környezetben a munkák kezdetét nem kell kijelölni. A felhasználó maga határozza meg, hogy mikor kezd új munkába, és azt milyen lépésekre bontja. Így a munkáknak interaktív környezetben nincsen azonosítója sem. Ez akkor is igaz, ha egyes operációs rendszerekben létezik a háttérmunka, a multitasking lehetősége, ami megengedi egy terminálnál ülő felhasználónak, hogy elindítson egy programot, és ne várja ki annak végrehajtódását. Ilyenkor az operációs rendszernek egyidejűleg kell vezérelnie a terminálnál ülő felhasználó több programját, ami ismét azonosítási problémát okoz. Ezért az ilyen interaktív környezetekben szükség van valamilyen más azonosítóra is, amelyet rendszerint sorszámozással szoktak megoldani. Az operációs rendszer a programok indításakor a következő sorszámot jelöli ki azonosítónak. Ezt nevezzük folyamatazonosítónak vagy folyamatsorszámnak. A folyamatsorszám azonban nem egy egész munkát, hanem csak egy munkalépést azonosít.

Interaktív környezetben tehát a munka egységét végül is egyedül a felhasználó határozza meg. Emellett a parancsnyelvek rendszerint lehetővé teszik, hogy több munkalépést egyetlen paranccsal is tudjunk aktivizálni. Ennek módja a parancsállományok készítése, amelyekben egy munkához tartozó tipikus lépések parancshívásai találhatók (lényegében ez teszi lehetővé a kötegelést az interaktív környezetekben). A parancsállomány neve az összefüggő feladatrészeknek konkrét azonosító nevet ad, ami felfogható munkanévként, de ilyenkor is a felhasználó dönt arról, hogy mit tesz a parancsállományokba, és hány parancsállományra bontja a teljes feladatot. Többcélú operációs rendszerekben az egyedi alkalmazásokhoz úgynevezett alrendszereket (pl. OS/TSO) hoznak létre. Ezekben az alrendszerekben a munka fogalma elég változó lehet, és eltérhet az alapoperációs rendszerben értelmezettől. Ugyanakkor az alrendszeri szolgáltatások az alaprendszer szolgáltatásaira épülnek. Következő fejtegetéseinkben, tipikus programozási szituációból kiindulva, a munka egységeként tekintjük egy feladat megoldását a forrásprogram lefordításától az eredmények kiszámításáig.

4.2. Munkafogadási fázis Munkafogadási fázisnak nevezzük azt, amikor a munka számítógépre kerül. Ez kötegelt feldolgozás esetén más időpont a felhasználónak, más az operációs rendszernek, minthogy a kötegelt feldolgozásnál a feladat gépre vitelét az üzemeltető személyzet manuálisan ütemezi. Ezt nevezik off- line ütemezésnek, ami jókora veszteségidőt okozhat a felhasználó szempontjából. A távoli munkabeviteli (RJE) támogatás és interaktív környezet esetén ilyen veszteségidők nincsenek. A kötegelt környezetek munkafogadási fázisában a munka egy bemeneti várakozó sorba kerül. Ha az operációs rendszer több bemeneti sort tud kezelni egyszerre, akkor a felhasználónak kell megadni, hogy melyik bemenő áramba akarja helyezni a munkáját. A munkák felvételét a várakozó sor(ok)ba a beolvasó és/vagy parancsértelmező program(ok) végzi(k). A beolvasók bemenetét a bemenő áramonként feladott munkák (job-ok), kimenetét pedig a bemenő várakozó sorok képezik. Funkciójuk lényegéből kiindulva a beolvasókat vezérlőáram-olvasóknak, az operációs rendszerben játszott fontos szerepük miatt pedig rendszerolvasóknak is nevezik. Programozó

Operátor

JOB --------> Off-line -------> ütemezés > RJE-JOB ---------------------->

Beolvasó

Bemenő sor

Beolvas, értelmez ---> Sorba állít

4.1. ábra. Munkafogadás A beolvasók a bemenő áramokból érkező munkákat azért helyezik el a bemenő várakozó sorokba, mert ritkán fordul elő, hogy a számítógépes rendszer azonnal képes őket kiszolgálni. Rendszerint sok munka összetorlódik, amit valamilyen módon kézben kell tartani. A már emlegetett szoftver spooling technika alkalmazásával az operációs rendszerek háttértáron eltárolják a várakozó munkák adatait, és azok legfontosabb jellemzőit az operatív tárban is nyilvántartják. Ezt az adatszerkezetet, mint nyilvántartási eszközt hívják bemenő sornak.

A rendszerolvasó parancsnyelven érti meg, hogy mit akarunk kérni a számítógépes rendszertől. Kötegelésnél ez a már korábban említett munkavezérlő nyelv (angolul: JCL), amellyel megadható: * a munka azonosítója (munkanév, job-név), és esetleg a munka egyes lépéseinek azonosítója, amiről a 4.1.-ben a munka definíciója kapcsán már volt szó; * a program(ok) végrehajtását kérő neve és munkaszáma; * a hívott program neve és helye az adattárakban; * az adatok vagy azok helye; * a szükséges perifériák adatai; * futásidő-korlát; * tárkorlát; * prioritás, határidő stb. A vezérlőnyelven írt munkát a beolvasó szintaktikusan kielemzi, és ha formai hibákat nem talál benne, akkor helyezi el a spooling bemenő sorában. A spooling állományban elfoglalt helyet feljegyzi a megfelelő sort nyilvántartó adatszerkezetekben. Ez biztosítja, hogy a későbbi munkafázisok hozzá tudjanak férni a munka eredeti adataihoz.

4.3. Munkakiválasztás A kiválasztási fázisban az operációs rendszer eldönti, hogy be tud-e ütemezni egy feladott munkát végrehajtásra. A döntés lehet elutasító is, ha a döntés pillanatában az operációs rendszer nem tudja biztosítani a szükséges erőforrásokat. Az ütemezőnek dönteni kell arról is, hogy több várakozó esetén kit részesít előnyben. Ezt tipikusan a munkák prioritása, és az előírt terhelési politika határozza meg. A kötegelt rendszerekben a kiválasztó program a főütemező. (Azért nevezik főütemezőnek, hogy megkülönböztessék az operációs rendszerben használatos más (alacsony szintű, közbenső) ütemezőktől, amelyeket később tárgyalunk.) A főütemező bemeneti adatait a bemeneti várakozó sorok képezik, kimenete pedig egy munkavezérlő blokk, amely a munkát azonosítja az operációs rendszer számára. A munkavezérlő blokkok reprezentálják a végrehajtási sort, vagy rövidebb néven munkasort, amely az éppen végrehajtás alatt álló munkákat tartja nyilván. Interaktív rendszerekben kiválasztási fázis nincs. A többcélú operációs rendszerekben a kompatibilitás végett a terminálkapcsolatot egy végtelen hosszúságú munkának tekintik. Bemenő sor

Főütemező

Munkasor

JOB11 MVBxx JOB12 -----------> Kiválaszt ----------------> MVB12 JOB13 0 (láncvég) JOB14 0 (láncvég) 4.2. ábra. Munkakiválasztás

4.4. Programfordítás A fordítási fázisban a munka végrehajtásához szükséges forrásnyelvű programok lefordítása történik. A fordítást befolyásolni lehet opcionális paraméterek megadásával. A fordítóprogramok bemenetei a munkában megadott forrásnyelvű programok, -- amelyeket spooling esetén átmenetileg háttértáron a bemeneti adatok között tárolnak, -- kimenetei pedig a korábban említett tárgymodulok. Fordítási fázis csak akkor kell, ha a munkához forrásprogramot is használunk. +----------------+ | Forráskönyvtár | +-------+--------+ | +---------------+ +----+----+ +------------+ | Forrásprogram |--->| Fordító-|------->| Tárgymodul | +---------------+ | program | +------------+ +---------+ 4.3. ábra. Programfordítás

4.5. Programszerkesztés A programszerkesztési fázisban az egységes belső formátumú tárgymodulokból és a tárgymodulkönyvtárakból származó szubrutinokból végrehajtható program jön létre. Az összeszerkesztést a programszerkesztő (angolul: linkage editor) végzi, amelynek a működését opcionális paraméterekkel (szerkesztő utasítások) a fordítóprogramokhoz hasonlóan tudjuk befolyásolni (tárhelyek definiálása, működésmód-paraméterek: kell-e kereszthivatkozási lista, a kód újrabeléphető stb.). A szerkesztő bemenetei a fordítási fázisban keletkezett tárgymodulok, a bennük hivatkozott tárgymodul--könyvtári szubrutinok, és a szerkesztésvezérlő utasítások. Kimenete egy vagy több betölthető programmodul, amely az operatív tárba betöltve végrehajtható. Ez a munkafázis sem minden munkához szükséges. +-------------+ | Tárgymodul- | | könyvtár | +------+------+ | +--------------+ +------v------+ | Tárgymodulok +--->| Program| +------------+ |--------------+ | szerkeszt ő |----->| Betölthet ő | +--------------+ | (Linkage | | modul | | Szerkeszt ő |--->| editor) | +------------+ | utasítások | +-------------+ +--------------+ 4.4. ábra. Programszerkesztés

A programszerkesztési fázis fő célja az, hogy a különböző programnyelveken megírt programokat is össze lehessen kapcsolni egyetlen programmá. Ennek feltétele, hogy a forrásprogramokat a fordítóprogramok egységes tárgymodul formátumra fordítsák. Az így lefordított rutinok könyvtárakban is tarthatók. A programszerkesztőket fel kell tehát készíteni szubrutinkönyvtárak kezelésére is. A programszerkesztés típusai: * fordítóprogram-szolgáltatás (vezérlőutasítások, paraméterek), * nyelvi támogatás (CALL szubrutinhívásokkal), * betöltőprogram-támogatás, * külön szerkesztőmenet szerkesztőprogrammal (ez a legelterjedtebb). A programszerkesztő bemenetei: * Szerkesztésvezérlő utasítások (direktívák), amelyek érkezhetnek a szabványos bemenetről vagy -- főleg interaktív üzemmódban -- a programhívás paramétereiből; * Átcímezhető programmodulok, amelyek az előző fordítási menetekből származnak; * Áthelyezhető (szubrutin)könyvtári modulok, rendszerint nyelvspecifikus, esetenként több, különféle tárgymodul-könyvtárból. A programszerkesztő kimenete(i): * Működőképes, de esetleg még mindig átcímezhető programmodul(ok) (szegmentált, átfedési {overlay} technikát alkalmazó programoknál mindig több modul keletkezik). A programszerkesztés eredménye háttértárba kerül: * vagy szekvenciális állományként, * vagy egy bináris programkönyvtár elemeként. A programszerkesztési művelet részletei: * A lineáris modulcím-tartományokat, amelyek mindegyikének a kezdőcíme rendszerint nulla (0) (a fix helyre címzett rendszerprogramok esetét kivéve), le kell képezni egy vagy néhány összefüggő, esetleg előírt átfedést mutató címtartományra. * A függetlenül fordított modulok más modulok belsejében szereplő belépési pontokra vagy külső címkékre történő külső címhivatkozásokat használhatnak. Ezeket a kereszthivatkozásokat a szerkesztőprogramnak fel kell oldania a modulokban szereplő belépési pontok és a külső hivatkozások összepárosításával (ilyenkor hiba is felléphet, ha a párosítást nem lehet teljes körűen és ellentmondásmentesen elvégezni: feloldatlan külső hivatkozási hiba, angolul: unresolved address, external error stb.). * Az átfedő modulok közötti közlekedést többnyire a programozónak kell megoldania. Megjegyezzük, hogy az átfedési (overlay) technika abból az időből származik, amikor a

hardverben az operatív tár igen szűk kapacitás volt (a drágaság miatt kis méretű tárakat szereltek a gépekbe). Manapság a RAM áramkörök olcsósága és a virtuális tárkezelés miatt egyre kevésbé gazdaságos a programfejlesztőket arra ösztökélni, hogy átfedési technikával korlátozzák a kifejlesztendő program címtartományát. Az átfedő szegmensek közötti közlekedés elbonyolítja az algoritmust, és rendkívül sok, kifejezetten l'art pour l'art számítástechnikai elemet kever a programba. Gondolni kell arra, hogy a programozóknak ezeket a programrészeket is be kell lőni, ráadásul ez igen mély operációs rendszeri ismereteket igényelhet, ami az alkalmazói programozóktól tömeges méretekben nem várható el. Más a helyzet, ha valaki rendszerprogramot ír, vagy nincs virtuális címzési lehetőség, vagy az adott hardveren címkorlátok vannak (az ilyen hardverek szerencsére rohamosan kihalnak -- így a jó nekünk, programozóknak!). Vegyük észre továbbá, hogy a szerkesztőprogramok működési elveinek megalkotásakor a strukturált és moduláris programozás támogatását tűzték ki fő célul. A külön fordítható kis méretű programmodulokat külön-külön is be lehet lőni, majd a végén a szerkesztőprogram segítségével integrálni lehet egyetlen monolit programmá. Megjegyezzük azonban, hogy ma már a monstre programok írásának kora is lejáróban van. Jóval gyorsabban dolgozhatunk, ha kis méretű, de rafináltan paraméterezhető segédprogram-készletre alapozzuk feladatunk megoldását. A konkrét feladatot bináris programkönyvtári rutinokra alapozva próbáljuk megoldani, és csak akkor írunk új programot, ha egy probléma a meglévő könyvtári elemekkel egyáltalán nem, vagy gazdaságosan nem oldható meg. Várható, hogy ilyen esetben is csak kis méretű programokat kell írni. Ezek belövése elég gyors, mert elmarad a monolit programoknál felmerülő, olykor igen keserves integrációs teszt. Ez a módszer igen jól támogatja a strukturált és a moduláris programozást, beleértve a programozói csoportmunkát is. Épp ezért választották a UNIX alapfilozófiájaként. A programszerkesztő direktívái sok operációs rendszerben bonyolult programozási nyelvet képeznek. A számítástechnika rohamos társadalmiasodása folytán egyre több az olyan programozó, akitől nem lehet elvárni ilyen bonyolult (és helytelen alkalmazás esetén nagy veszélyeket rejtő) ismeretek megtanulását. A szerkesztőmenet ezért az alkalmazók felé egyre szegényesebb arcot mutat, jobbára teljesen elfedi őket a fordítóprogram, amely automatikusan megszervezi a lefordított program összeszerkesztését. Nem is beszélve az igen magas szintű nyelvi rendszerekről (mesterséges intelligencia, szakértői rendszerek stb.)! A programszerkesztő profi használata megmarad szűk körű vájt fülűek (így 2000. tájékán: hackerek, guruk -- ZSP/2K.9.21.) privilégiumának. Ezek erőfeszítéseit sem kíséri arányosan nagyobb eredmény. Az utóbbi három bekezdésből megítélheti az olvasó, milyen mértékben egyszerűsödik a programozói munka a hardver és a rendszerszoftver fejlődésével. Egyszerűen nem kell annyit erőlködni, mint régen. Nem is szabad! Ne dőljünk be az idősebb korosztályok izzadságszagot kedvelő munkastílusának! Biztonságos megoldásokra kell törekedni, de a szükségesnél bonyolultabbakra nem.

4.6. Programaktiválás és erőforrás hozzárendelés Az aktiválási, hozzárendelési fázis a munka egy lépésének elvégzéséhez szükséges program futási környezetét teremti meg a JCL-utasításokban jelzett erőforrásigények (perifériák, adatállományok, tármezők) alapján. Az aktiválást az operációs rendszermag moduljaira támaszkodó speciális program, az iniciátor, végzi. Fontos kérdés, hogy az erőforrások lekötése mikor történik. Egy operációs rendszert annál rugalmatlanabbnak tekinthetünk, minél korábban köti le -- a felhasználás időpontjához képest -- a szükséges erőforrásokat. A rugalmatlanság következménye az lehet, hogy a munka hosszú időre megfog egy perifériát, jóllehet csak egyetlen, apró bemenőadathoz használja mindjárt a futás kezdetén. Helyes, ha a lefoglalásra vonatkozó döntések minél későbbre lehet halaszthatók, vagy át lehet helyezni a végrehajtási fázisba. A dinamikusabb kezelés ára a nagyobb rendszeradminisztrációs erőforrásigény (overhead).

Az iniciátor program készít egy bejegyzést az operációs rendszer nyilvántartásában, és esetleg adhat neki egy belső azonosítót: folyamatazonosítót, illetve folyamatsorszámot. A vonatkozó nyilvántartást folyamatsornak vagy taszksornak, a bejegyzést pedig folyamatvezérlő blokknak (angolul: Process Control Block -- PCB), vagy taszkvezérlő blokknak (angolul: Task Control Block -- TCB), szokták hívni. (Ha egy program a futása során egy másik programot (alprogramot) aktivizál, akkor ez új azonosítót és új bejegyzést kap. Ezeket gyermekfolyamatoknak vagy szubtaszkoknak hívjuk.) Munkasor

Iniciátor

MVBxx -------->

Taszksor

TCB(nnnnn) Er őforrás ---------------> TCB(nnnnn+1) lekötés 0 (láncvég)

4.5. ábra. Programaktiválás és erőforrás hozzárendelés

4.7. Programbetöltés A betöltési fázisban az operációs rendszer helyet biztosít az operatív tárban a munkalépés programjának (kivéve, ha az eleve fix címre akar töltődni), és betölti. A betöltést vagy külön betöltőprogram, vagy az operációs rendszer betöltő-modulja végzi. A betöltőprogram bementét a betölthető programmodulok képezik, kimenete pedig az operatív tárba kerül. A betöltés során a modulok címeit a betöltőprogram -- ha szükséges -- átcímezi úgy, hogy a program az adott helyen végrehajtható legyen. A betölthető programmodulok programszerkesztés eredményeként keletkeznek. A betöltőprogramnak ezeket többnyire újra át kell címeznie, mert multiprogramozott környezetben és valós tárak használata esetén előre nem lehet tudni, hol lesz szabad tármező, amikor a betöltő helyet foglal a programnak (ismét kivéve a fix helyre töltődőket). Az átcímzési műveletet programáthelyezésnek nevezzük. A programáthelyezést statikusnak nevezzük, ha az csak betöltéskor történhet, később már nem. A dinamikus programáthelyezés lehetővé teszi, hogy a program szükség esetén működés közben is áthelyezhető legyen az operatív tár más tartományába. Ez biztosíthatja a legrugalmasabb tárgazdálkodást. Amíg nem voltak hardver virtuális tárak, addig a programáthelyezés a betöltőkkel szoftver úton történt. Virtuális tárak esetén más a helyzet. Igazi virtuális címzést biztosító operációs rendszerek használatával ugyanis minden programnak rendelkezésre áll a hardverrel címezhető teljes címtartomány (nullától a maximumig!, ha nem kell kerülgetni rendszerprogramoknak lefoglalt címtartományokat vagy a hardver speciális működését kiváltó címeket). Virtuális tárkezelés esetén tehát átcímzésre a betöltéskor elvileg nincs szükség, de még mindig gondokat vethet fel a lapokra tördelt programrészek működésének biztosítása a fizikai lapokon. Emiatt a virtuális tár technika egyáltalán nem biztos, hogy egyszerűbb megoldást eredményez. (Mégis, ha a virtuális tárakat korábban felfedezték volna, talán másképpen alakult volna az operációs rendszerek egész tárkezelése.)

4.8. Programvégrehajtás A végrehajtási fázis jellemzője, hogy a munkalépés programja aktív a rendszerben, a

multiprogramozott környezetben versenyez az erőforrásokért. Egyáramú rendszerben a munka folyamatosan fut, a számlázandó idő akár "faliórával" is mérhető. Multiprogramozott környezetben viszont a végrehajtási idő és a felhasznált idő szükségszerűen eltérő. A végrehajtási idő olykor lényegesen hosszabb lehet, mint multiprogramozás nélkül. Ez a felhasználó szempontjából veszteségidő. Ezalatt azonban a munka nem állandóan aktív, és a számlázórendszer feladata, hogy csak azokat az időket és erőforrásokat számítsa fel a felhasználónak, amit ténylegesen felhasznált. Előfordul, hogy két olyan munka kerül össze a multiprogramozott környezetben, amelyek "egymást ütik". Tipikus példa erre az olyan eset, amikor két program ugyanazt a mágneslemezes adatállományt olvassa aszinkron módon. Ilyenkor a lemezegység olvasófeje oda-vissza rángatódzik, ami igen nagy időveszteségeket okoz. Ha a két program eltérő időintervallumban futhat, akkor érthető okoknál fogva gyorsabban befejeződhetnek, sőt a hardver igénybevétele is kedvezőbb. Az adott szituációt elég nehéz programozottan kiszűrni, ezért még mindig sok függ az alkalmazók odafigyelésétől, és az üzemeltetés manuális ütemezési tevékenységétől. Jellemző, hogy az említett szituációban az operációs rendszer a rossz hatásfokú működésből eredő terheket könyörtelenül leszámlázza a két program indítójának, holott ők esetleg nem is tehetnek róla.

4.9. Záró fázis Amikor egy program lefut, az operációs rendszernek még egy sereg teendője marad. A program befejeződése után vissza kell venni tőle a lefoglalt erőforrásokat, és különféle adminisztratív műveleteket kell végrehajtani. Ezt vezérli a terminátor program. A további tipikus feladat a háttértárra vitt nyomtatókimenet átadása a nyomtató spooling rendszernek, azaz elhelyezés a kimeneti sorban. Ha a spooling rendszer végez a munka eredményének kilistázásával, akkor az operációs rendszer véglegesíti a munkára vonatkozó számlázási adatokat, és a munkához tartozó táblázatokat törli, hogy a már érdektelen információk ne terheljék a rendszer táblázatait.

4.10. Rendszerfolyamatok Az operációs rendszer saját feladatai szintén munkaként merülnek fel a számítógépes rendszerben. Ezeket a speciális feladatokat rendszerfolyamatoknak, rendszertaszkoknak nevezzük (több elnevezés is használatos). A tipikus rendszerfolyamatok: * * * * * * * *

beolvasó (spooling munkafogadó), főütemező (munkakiválasztó), iniciátor (aktivizáló), terminátor (befejező), nyomtató (spooling listázó), nyelvi fordító, programszerkesztő, betöltő stb.

Ezek a munkák többé-kevésbé szintén átmennek a fejezetben tárgyalt munkafázisokon. Ezeket is fogadni kell, ki kell választani végrehajtásra, aktivizálni kell stb. A rendszerfolyamatok esetében ez privilegizált módon, előnyök biztosításával, esetenként speciális üzemmódban történik. Egyes rendszerfolyamatok a rendszertöltéskor automatikusan elindulnak (például a főütemező), míg mások (például a beolvasók, a nyomtatók) csak operátori beavatkozásra indulnak. A kapcsolódó vezérlőblokkok (PCB, TCB stb.) állandóan megmaradnak az operációs rendszer

nyilvántartásaiban, és rendszerint a táblázatok elején foglalnak helyet. A megfelelő programok munkahiány esetén elalszanak (de nem halnak meg), és amint valami történik, rögtön felébrednek. Ez tipikus real-time (eseményvezérelt) jelleg.

4.11. Mintapéldák Példa gyanánt elsősorban ismét az IBM kötegelt operációs rendszerei említhetők, amelyekről a 2. fejezetben részletesen volt szó. Így például az OS munkafogadási fázisát a READER beolvasóprogram valósítja meg. A kiválasztást az OS magas szintű ütemezője, a MASTER SCHEDULER főütemező program végzi. Az OS akkor indít egy programot, ha van olyan (szabad) INITIATOR (iniciátor) program, amely indítani képes. Az iniciátor lefoglalja az igényelt erőforrásokat, és az OS SUPERVISOR-ával betölteti a behívandó programot. A SUPERVISOR megfelelő tármezőt foglal le, betölti és elindítja a programot. Az OS a nyomtatóra szánt kimenetet félreteszi mágneslemezre. Amikor a program jelzi, hogy véget ért, akkor a TERMINATOR program intézi el a záróteendőket. Felszabadítja a még foglalt erőforrásokat, és gondoskodik a kinyomtatásra szánt adatok átadásáról a WRITER nyomtatóprogramnak. Miután a nyomtatóprogram sorra kerítette és kinyomtatta a munka eredményét, a munka teljesen törlődik a rendszer táblázataiból. A terminátor program behívja maga után az iniciátort (ez csak logikailag értendő, az OS-ben az iniciátor/terminátor fizikailag egyetlen program). Ilyenkor az iniciátor szabaddá válik újabb program indítására. A multiprogramozás fokát az OS-ben tehát elsősorban az határozza meg, hogy hány INITIATOR-t indítottak el az üzemkezdet óta. Az operátorok a multizás növelésére indíthatnak újabbakat, de le is állíthatnak egyeseket, ha túl nagy a rendszerterhelés. Az interaktív rendszerekről azt írtuk a főszövegben, hogy azoknál a felhasználónak magának kell megszerveznie a munkát. Így munkafogadó program nincs, az erőforrások lefoglalásáról, és a kiválasztásról a felhasználó maga dönt. A programindítást a parancsértelmező program végzi a felhasználó direkt utasítására. Az ilyen operációs rendszerekben a programszerkesztő és betöltő program tér el legkevésbé a kötegelt rendszerekben szokásosaktól. Az utóbbi időben azonban a számítástechnika erős társadalmiasodása olyan helyzetet teremtett, hogy egyre több olyan interaktív felhasználó jelentkezik, akire nem lehet rábízni a munka megszervezését az interaktív környezetben. A szoftvergyártók ezért foolproof (bolondbiztos) ún. dedikált szoftverek létrehozására törekednek, amelyek a felhasználónak természetesebb -- nem túl "komputerszagú" -kapcsolattartási nyelvet biztosítanak: menüből választható, előre megszervezett, munkameneteket támogatnak. Ezekben a programokban persze sok hasonló elem van. Ha ezeket jól kielemezzük, akkor készíthetünk általános menüvezérlő szoftvereket, amelyeket már számítástechnikailag kevésbé kvalifikált alkalmazók is felhasználhatnak interaktív feladataik racionális megszervezésére. Érdekes, hogy ilyen szoftverek előszeretettel éppen a PC-k körében terjednek. Ennek az az oka, hogy a mai nagy teljesítményű személyi számítógépeknél sem annyira magánügy már, hogy milyen a gép kihasználtsága. Itt is cél, hogy a lehető legtöbbet hozzuk ki belőlük (ebből a szemszögből nézve az OS/2 ugyan csak egy kicsi, de fontos lépés lehet előre a multitaskingjával!). Tipikus PC-s munkaszervezők: PathMinder, XTREE, FRAMEWORK, GEM Desktop, WINDOWS, valamint a sokáig várva várt Presentation Manager az OS/2-ben, és az MS--DOS 4.0-s változata, hogy csak néhányat említsünk. (Azóta jött a tisztességesen multiprogramozható W9x, WNT és W2K -- anno 1995-2000-ig, ZSP.2K.9.25. 2001: WXP.) A PC-ken továbbá még egy "kór" terjed, az ún. integrált szoftverek filozófiája. Ezek nemcsak a munkafogadást és indítást, hanem egy típusfeladat teljes lépéshalmazát igyekeznek magukba integrálni és támogatni. Az alkalmazókat a maximális mértékben mentesítik a munkaszervezés viszontagságaitól, amiért a nem számítógépes alkalmazók igen hálásnak mutatkoznak. Ilyen típusú szoftverek (a fentiekkel átlapolva): a TURBO PASCAL, a LOTUS 1-2-3, a SYMPHONY, a

DBASE az ASSIST-tal, a FRAMEWORK, a GEM moduljai, a WINDOWS, de a felsorolás persze nem teljes. Már a segédprogramokat is ilyen stílusban szervezik. Ez látható a PCTOOLS-nál, ami a hajdani nagygépes IBM DITTO segédprogram filozófiájának jól elkapott interaktív, menüvezérelt, bár karaktergrafikás és billentyűzetről kezelhető megfelelője (legalább a MICROSOFT egerét ismerhetné, mint annyi más jó szoftver, pl. a NORTON programok). Megjegyezzük, hogy az integrált szoftverkörnyezet egyáltalán nem mai ötlet. A UNIX már 1969-ben ezen az elven alapult. Az IBM TSO továbbfejlesztett változatai (SPF stb.) szintén ezt a filozófiát igyekeztek megvalósítani még a 70-es években.

4.12. Gyakorlatok 4.12.1.

Mi a feladatok egysége a számítástechnikában?

4.12.2.

Van-e tipikusan megkülönböztetett feladategység interaktív környezetben?

4.12.3.

Mi történik a munkafeladási fázisban?

4.12.4.

Mi van a bemenő sorban?

4.12.5.

Mi az off-line ütemezés?

4.12.6.

Van-e veszteségidő az RJE-JOB-oknál?

4.12.7.

Mi a munkavezérlő blokk?

4.12.8.

Hogyan történik a munkakiválasztás?

4.12.9.

Mit csinál a főütemező?

4.12.10.

Hogyan történik a programok fordítása?

4.12.11.

Mi a tárgymodul?

4.12.12.

Milyen bemenő adatokkal dolgozik a szerkesztőprogram?

4.12.13.

Mi a betölthető modul?

4.12.14.

Hogyan teremtjük meg a program futtatási környezetét?

4.12.15.

Mi az iniciátor?

4.12.16.

Mi az előnye és hátránya a rugalmas erőforrás kezelésnek?

4.12.17.

Hogyan vesszük nyilvántartásba az elindított programokat?

4.12.18.

Mi történik a programbetöltéskor?

4.12.19.

A futtatási időben támadhat-e veszteségidő? Mikor? Miért? Kell-e érte fizetni a felhasználónak?

4.12.20.

Mi történik egy program lefutása után?

4.12.21.

Mit nevezünk rendszerfolyamatnak?

4. Milyen kezelésmódot igényelnek a rendszerfolyamatok?

OS05v08,2K.9.24,ZSP

5. RENDSZERSZOLGÁLTATÁSOK

5.1. Alapkoncepció A számítógépes rendszer pár szolgáltatását operációsrendszeri szolgáltatásnak (rövidebben rendszer-szolgáltatásnak) nevezzük. Ez a kör függ attól, hogy az adott számítógépes rendszer szoftverének mely elemeit soroljuk az operációs rendszer elemei közé. Általában a rendszerszolgáltatásokhoz soroljuk az alkalmazók elég széles körében használt szoftverelemeket. A nem operációs rendszeri szolgáltatások egy része is lehet elég széles körben használható. Ez a már említett rendszerközeli szoftver, amelyet inkább segédprogramoknak nevezünk. A rendszerszolgáltatások nem feltétlen kötődnek a rendszermaghoz, de megvalósításuk a rendszermag szolgáltatásait intenzíven használó, rendszerfolyamatokként futó ún. rendszerprogramokkal történik, amelyek az operációs rendszerben kifejezetten nekik biztosított privilégiumokat élveznek. Az operációs rendszer felügyelete alatt működtetendő programokat tekintve vannak futtatás előtti és futtatás alatti rendszerszolgáltatások. Speciális eset, amikor az operációs rendszer egy szolgáltatást saját magának nyújt.

5.2. Vezérlőáram-kezelés Mint arról már többször beszéltünk, a kötegelt üzemű operációs rendszerek bemenetére érkező munkákat a vezérlőáram-olvasó, vagy más néven rendszerolvasó (angolul: system reader) fogadja. A kötegelt üzemmódban a parancsokat kötegekben összegyűjtjük, és átmenetileg mágneslemezen tároljuk. Ez a szoftver spooling technika, amelyről már szintén volt szó. A mai vezérlőáramkezelők teljesen a szoftver spoolingra alapozva működnek. Az összegyűjtött parancsok végrehajtása külön menetben történik. (Interaktív üzemmódban a parancsok egyenként, azonnal végrehajtódnak, de a rendszerolvasók ritkán használhatók interaktív üzemmódban.) A kötegelt üzemmód rendszerolvasóit operátori kezdeményezéssel kell indítani. A beolvasott munkák a bemenő várakozó sorba kerülnek, amiről az előző fejezetben már volt szó. A futási eredmények a szoftver spooling elvei szerint szintén sorba állnak. Ez a nyomtatósor. A nyomtatósorból az eredményeket a rendszernyomtató program nyomtatja ki. A rendszernyomtatókat szintén operátori kezdeményezéssel kell indítani. Operátori kezdeményezésre a rendszerolvasók és -nyomtatók le is állíthatók majd újraindíthatók. A rendszerszolgáltatások esetében tipikusan igaz, hogy a rendszerfolyamatok vezérlése, mivel

különleges elbírálást igényel, az üzemeltető személyzet feladata. A szintaktikus ellenőrzés többé-kevésbé a rendszerolvasók feladata, de olykor ezt későbbi rendszerelemek végzik (a főütemező vagy az iniciátorok). A felhasználónak nem öröm, ha a JCLhiba csak a futáskor derül ki, de a dinamikus erőforrás-foglalási stratégia időnként nem teszi lehetővé, hogy elég messzire lássunk előre. Kompromisszumos megoldásokra törekednek. A rendszerolvasót általában elválasztják az ütemezőktől, mert külön-külön rendszerfolyamatkénti aszinkron működésük kedvezőbb "munkakeverék" (angolul: jobmix) összeállítását teszi lehetővé. Sőt, a főütemezővel konkurens több rendszerolvasót is működtetni lehet (több bemenőáramú rendszerek). Így a nagy teljesítményű hardverek számára kellő mennyiségű munkát lehet a számítógépes rendszerbe vinni.

5.3. Tárkijelölés és programbetöltés A programok betöltése multiprogramozott környezetben szinkronizálást igényel. Ezt az operációs rendszer tárkezelési szolgáltatásaira épülő betöltőprogrammal lehet kézben tartani. A programokat fordításkor csak akkor lehet fix címre elhelyezni, ha azon a tárterületen más program általában nem futhat. Ez csak a rendszerprogramoknál fordulhat elő. A normál programokat mindig átcímezhetőre kell fordítani, alacsonyszintű programnyelveken pedig a programozónak áthelyezhető programokat kell írnia. A betöltőprogram gondoskodik róla, hogy, ha szükséges, a program az általa igényelt fix címre kerüljön. Általánosabb esetben, ún. normál programoknál viszont inkább helyet foglal a programnak az operatív tárban, majd a program kritikus részeit átcímezi úgy, hogy az adott tárterületen működőképes legyen. A programok átcímzése egyszerűbb, ha a hardver programáthelyezési támogatást tud nyújtani. Ennek hiányát csak bonyolultabb betöltőprogrammal lehet kompenzálni. Az IBM 360/370-es hardvereknek például nincs ilyen szolgáltatásuk, ami azzal a "krónikus" következménnyel jár nemvirtuális tárkezelésű operációs rendszerek használata esetén, hogy a tár a munka során felaprózódik sok kis méretű szabad területre, amelyeket nem lehet menetközben összegyűjteni. A problémát sokszor leggyorsabban csak a rendszer átmeneti leállítása árán lehet feloldani. Ennek megfelelően nagyra értékelhető, hogy a ma -- de még inkább a jövő -- számítógépkorszakát talán meghatározó INTEL 80286/80386-os mikroprocesszorok, és a VAX-kategóriájú miniszámítógépeknek van automatikus programáthelyezési architektúrája. Virtuális tárkezelésnél teljesen az operációs rendszer magánügye lehet egy programszegmens elhelyezése. A programok a szegmenseikre nem azok címével, hanem egy táblázatindexszel hivatkoznak. A táblázatbeli címeket megszakításkor az operációs rendszer az üzemi körülményektől függően bármikor megváltoztathatja. A program újabb beütemezésekor a hardver a vezérlést a virtuális tárkezelés dinamikus címfordítójára támaszkodva automatikusan az új helyre adhatja. Így virtuális tárkezelésnél a valós tárban szabadon maradó helyek is könnyedén összegyűjthetők egy darabba, mert csak az összegyűjtés során útba került, és eltologatott szegmensek új kezdőcímeit kell bejegyezni a megfelelő indextáblázatokba. A virtuális tárkezelésű rendszerekben elvileg teljesen lineáris címmező áll a programok rendelkezésére. Néhány rendszerben azonban még belezavarnak a képbe a hardverarchitektúra sajátosságai. Előfordul például, hogy bizonyos tárterületeket kerülgetni kell. Ez többnyire a fordítók és a betöltőprogramok feladata. Tipikusan ilyen eset az INTEL 80286/80386-os családot használó IBM PC architektúra, amelyben az alsó 1 megabájtos címtartományt (igen fix kiosztásban) a tárba

ágyazott perifériakezelés és az MS--DOS operációs rendszer "őskövületei" zavarják. Ezért a PC-s operációs rendszerekben vagy kerülgetni kell az alsó 1 megabájt fix címeit, vagy -- ahogy az OS/2 tervezői is tették -- az egészet odadobjuk egy MS--DOS partíciónak (DOS kompatibilitási doboz). (Szerencsére, még marad további 15 megabájtnyi címmező! -- I80286 korlát, ZSP. 2K.9.24.)

5.4. Szerkesztőmenet A programszerkesztő programok (angolul: linkage editors) különálló programmodulokból a futóképes programok összeállítását végzik, mint azt korábban és részletesebben a 4. fejezetben megtárgyaltuk. A programszerkesztők erősen igénylik az alsóbb operációs rendszeri szolgáltatásokat, ezért nem sima segédprogramoknak, hanem rendszerelemeknek tekintjük őket. (Szemben a forrásprogramok írásához használatos szövegszerkesztőkkel, más néven editorokkal, amelyeket segédprogramoknak tekintünk akkor is, ha egy-egy editor sokszor igen mélyen beépül némely operációs rendszerbe.) A programszerkesztők annyiban mégis segédprogram jellegűek, hogy nem a rendszermag részei, ezért normál folyamatként futnak, nem úgy, mint a főütemező és más rendszerfolyamatok. A segédprogram jelleget támasztja alá még az a körülmény is, hogy amíg más rendszerfolyamatok működését elsősorban az operációs rendszerben kitűzött politikák vezérlik, addig a programszerkesztő működését szinte teljes mértékben az alkalmazó befolyásolhatja a szerkesztésvezérlő utasításokkal.

5.5. Magas szintű ütemezés Kötegelt üzemmódban a bemenő áramból (más néven: vezérlő áramból) érkező és a végrehajtási sorba helyezett munkák végrehajtását külön operációs rendszeri modul, az ütemező végzi. Az operációs rendszerben azonban több ütemező is működik, ezért a munkák végrehajtását beütemező programot megkülönböztetésül főütemezőnek (angolul: Master Scheduler) nevezzük. Az 1.2. fejezetben a számítógépes rendszer üzemeltetői szemszögből vizsgált rétegződésével kapcsolatban említettük az ütemezési réteget (lásd: 1.3. ábra), amely az operációs rendszeri réteg felett van. A főütemező ebben a rétegben helyezkedik el, tehát az operációs rendszernél magasabb hierarchia szinten. Ezért mondjuk, hogy a főütemező magas szintű ütemező. A magas szintű ütemező így nem az operációs rendszermag része, hanem egy rendszerfolyamat a számítógépes rendszerben, ami más folyamatok működését vezérli aszinkron konkurens üzemmódban.

Az ütemező aktivizálódhat: * induláskor automatikusan, * operátori kezdeményezésre, * eseményvezérelten (valós idejű és tranzakciós környezetekben, megszakításokra reagálva), * folyamatvezérelten (a programok megkapják a vezérlést az ütemezőtől, amit visszaadnak neki; ez az egyfelhasználós egyáramú üzemmódra jellemző, de alkalmazása ott is egyre ritkább, például a programozott/sorrendi vezérlőkben fordul elő). Üzemindításkor (betöltéskor, angolul: boot), amikor az operációs rendszer a főütemezőt indítja, annak folyamata többnyire első folyamatként, az inicializálási folyamat során keletkezik (a folyamatok táblázatában ezért automatikusan az övé az első hely). Ezután a főütemező gondoskodik további folyamatok létrehozásáról, amelyek egyike lehet a rendszer indításakor az operátorral kapcsolatot tartó rendszerindító folyamat. Ennek segítségével az operátor is kezdeményezheti különböző folyamatok indítását (például a már említett rendszerszolgáltatásokat, a beolvasó és nyomtató programokat). A rendszer akkor működik a leggazdaságosabban, ha a főütemező minél ritkábban aktivizálódik, és működéséhez nem von el túl sok erőforrást a számítógépes rendszertől (angolul: overhead). Az ütemezést a főütemező előírt politika szerint hajthatja végre. Ez igen erősen rendszerfüggő. A munkakiválasztás a pillanatnyi munkasortól és az erőforrás-kapacitásoktól függ. A dinamikus erőforrás-kezelő(ke)t olykor beépítik a főütemezőbe, de a dinamikusabb rendszerműködés csak különálló, aszinkron konkurens módon működő kezelőprogramokkal oldható meg. Ezek sem a rendszermag részei -- akár a főütemező, -- hanem magasabb rétegekben találhatók, de az erőforrások foglalásához igen alapvető rendszermag-szolgáltatásokat vesznek igénybe. Indításuk részben automatikus a rendszer indításakor, részben pedig az operátor vagy valamelyik ütemező kezdeményezheti indításukat. Ebbe a kategóriába tartoznak a korábban már emlegetett iniciátor és terminátor programok.

5.6. Működésoptimalizálás A főütemező a rendszerolvasó programok által a végrehajtási sorba helyezett munkák indítását vezérli. Az ilyen vezérlési rendszerben néha zavarok támadnak, mert a munkakeverék egyik eleme olykor túl agresszíven birtokba veszi a rendszer erőforrásait. A főütemező ezen nem tud változtatni, hiszen ő már átadta a munkát végrehajtásra az alacsony szintű ütemezőnek, amely a központi egység használatát ütemezi. Ezt az ütemezőt a továbbiakban megkülönböztetésül (az angol dispatcher elnevezés nyomán) diszpécsernek fogjuk hívni. A diszpécsernek igen sok dolga van ezen az alacsony szinten, ezért vigyázni kell arra, hogy mit veszünk bele az algoritmusába. Ha túl bonyolult az algoritmus, akkor az egész számítógépes rendszer erősen lelassul. Az egyszerű algoritmus viszont nem teszi lehetővé elég széles látókörű ütemezési politika megvalósítását. A gyakorlat az, hogy a diszpécser csak lokális optimumokat vizsgál a kiválasztási döntésekben. Nagyteljesítményű rendszerek gazdaságos működtetéséhez ez nem elegendő. Ezért bevezettek egy további ütemezőt, a közbenső (szintű) ütemezőt, amely a rétegszerkezetben valahol félúton helyezkedik el a magas- és az alacsony szintű ütemező között. A közbenső ütemező feladata -- mint a mondottak után várható -- a globális optimalizálás. Ennek

megoldására állandóan figyeli a munkák előrehaladását. Ha egy munka nem halad elég gyorsan a rendszerben, akkor például prioritásának ideiglenes megemelésével segíthetünk rajta, mert a prioritás növelésével nő annak az esélye, hogy -- mások rovására -- beütemeződjön. Bonyolultabb optimalizálási algoritmusok súlyos esetben lehetővé teszik egyes munkák ideiglenesen kiiktatását az alacsony szintű ütemezésből, hogy az erőforrásra éhező más munkák egyáltalán szóhoz tudjanak jutni. Amint az éhezés megszűnik, a közbenső ütemező a kivételezéseket sorra megszünteti, nehogy ellenhatásként a korábban elsőbbséget kérő munkák kerüljenek hátrányos helyzetbe. A közbenső ütemezők általában segíteni szokták a kis erőforrás-igényű munkákat, hogy azok minél gyorsabban átjussanak a rendszeren, de támogatják a túlzottan lassan haladó munkákat is (például az idő előrehaladtával arányosan növeli prioritásukat), hogy siettesse a kijutásukat. Bonyolítja a helyzetet, ha a számítógépes rendszer univerzális üzemmódban dolgozik. Ha például valós idejű környezete is van, akkor a valós idejű feladatokat mindig ki kell szolgálni az előírt időkorláton belül, és minden más igény kiszolgálása csak ezután jöhet. Az OS/2 operációs rendszerben például 32 prioritási szint van. A 0 -- 15-ös prioritásszinteken időosztásos üzemmód működik, míg a 16 -- 31-es magas prioritásokat a valós idejű alkalmazásoknak tartották fenn. Ez a módszer a valós idejű alkalmazások elsőbbségét -- tulajdonképpen kifejezett kivételezés nélkül, automatikusan -- biztosítja. Ugyancsak a prioritások alkalmas kiosztásával szabályozzák az IBM 360/370-es OS operációs rendszerekben a TSO időosztásos alrendszer működését. A rendszergeneráláskor beállítható prioritásintervallumba eső folyamatok (IBM terminológiával taszkok) kiválasztásakor az alacsony szintű ütemező időszeleteléses kiválasztási algoritmust követ, míg az intervallumon kívül eső prioritások esetén prioritásvezérelten működik, ami a kötegelt feldolgozások üzemeltetésénél fontos.

5.7. Alrendszerek kezelése Az alrendszerek az operációs rendszerekben speciális jelentéssel bírnak. Homogén alkalmazói kör speciális igényeinek egyszerűsített kiszolgálását teszik lehetővé. Szolgáltatásaik alapja az operációs rendszeri interfész, amelyre egy új réteget borítanak. Ez az ún. alrendszeri réteg, amelynek a szolgáltatásait az alrendszeri interfészen át lehet elérni. Olyan részrendszer, amelyik egy magasabb szintet képező rétegben van: +-------+-------+-------+----------+----------+----------+ | | | | | | | | A l r e n d s z e r i | | | | |a l k a l m a z á s o k| | | | | | | | Al| Al| Al| +-------+-------+-------+ kal| kal | kal| | Alrendszeri interfész | ma| ma| ma| +-----------------------+ zá| zá| zá| | Alrendszeri | sok | sok | sok | | funkciók | | | | +-----------------------+----------+----------+----------+ | Futtatási környezet interfész | +--------------------------------------------------------+ | M E G A G É P | +--------------------------------------------------------+ 5.1. ábra. Alrendszeri rétegződés

Tipikus alrendszerek az univerzális operációs rendszerek programfejlesztő alrendszerei. Ilyen volt például az IBM BASIC és APL nyelvi alrendszere az IBM DOS-ban, és ilyen a TSO az OS-ben. Az alrendszerek tipikus szolgáltatásai: * szövegszerkesztők (esetleg nyelvspecifikusak), * interpreterek, * fordítók, szerkesztők, betöltők egy nyelvhez. Az IBM ebben a kategóriában emlegeti a JES(OS)-t és a POWER(DOS)-t, mint integrált kötegelést támogató alrendszert, bár ez egy kicsit sántít. A JES és a POWER az alábbi fázisokat vonja össze: * * * *

beolvasó (feladatfogadó), spooling, kiválasztás, aktiválás.

Így a JES (= Job Entry Subsystem -- munkabeviteli alrendszer) és a POWER (nem jellemző jelentésű akronim) a fenti definíció szerint azért nem alrendszer, mert nem csak egy szűk felhasználói kört érintenek, hanem egy általános célú munkafogadó és spooling programrendszert takarnak. Az JES az OS/VS rendszerek olvasó, nyomtató, magas szintű ütemező, sőt erőforrásfoglaló szolgáltatásait foglalja magában, amelyre minden számítógép felhasználó támaszkodik, akár kötegelt, akár időosztásos üzemmódban dolgozik. Ezzel szemben az OS rendszerek időosztásos opciója (ahogy az IBM nevezi, angolul: TSO = Time-sharing Option) nem más, mint egy igazi operációsrendszeri alrendszer. Speciálisan a programfejlesztést végző programozók munkájának hatékony támogatására kihegyezett alrendszer. A technikai megvalósítást tekintve egy alrendszer: * "integrált" programcsomag egy funkcióhalmazra, amely összefüggő feladatkört fed le; * a felhasználóknak az eredeti operációs rendszer interfészétől eltérő -- egyszerűbb -interfészt biztosít. A JES tehát azért sem alrendszer, mert nem képez integrált futási környezetet, hiszen lényegében csak a beolvasásra szakosodott részrendszer. Elemezhetjük ennek kapcsán a rendszerszolgáltatások és az alrendszeri szolgáltatások viszonyát. A rendszerszolgáltatások: * általánosan, relatíve ritkán használt szolgáltatások, amelyeket minden felhasználó elérhet. Alrendszeri szolgáltatások: * intenzíven használt, de csak a felhasználók szűk köre érheti el. A számítógépek hardver és szoftver fejlődését érdemes elemezni, mert kimutatja, hogyan váltak az alrendszerek egyre bonyolultabbá. Az operációs rendszerek tervezésénél eleinte nem gondoltak alrendszerekre, mindent egy közös operációs rendszeri interfésszel akartak kiszolgálni. Új szolgáltatási igények bevezetése azonban ebben a filozófiában egyenlő volt az operációs rendszer folytonos turkálásával, ami nem túl üdvös dolog. Rájöttek, hogy elég egy egyszerűbb szolgáltatáshalmazt biztosító interfészt készíteni, a

különleges eseteket pedig alrendszeri szolgáltatásokra kell bízni. Új igények kielégítését elvileg három módon biztosíthatjuk, amit az 5.2. ábra elemez. +-------------------+-------------------+----------------------+ | Beépítés a régi | A régi interfész |A régi interfész fölé | | interfészbe | teljes cseréje |alrendszeri interfész | | | | kiépítése | |(bonyolult, lassú | (veszélyes, |(egyszerű, de hatásfok│ | funkciók) | fáradságos) | csökkenés léphet fel)| +-------------------+-------------------+----------------------+ 5.2. ábra. Az alrendszer kiépítés elemzése A legrugalmasabb megoldást az alrendszeri interfész kiépítése tudja biztosítani, mert: * a rendszerkiterjesztés problémája a minimumra csökkenthető; * az alkalmazók kiszolgálásának szervezése optimalizálható; * új alkalmazások implementálása felhasználó-specifikus alrendszeri interfész kiépítésével érhető el.

A fejlődési tendenciákat, architektúrákkal jellemezve, az 5.3. ábra mutatja: A/ Egymenetes rendszer

B/ Multiprogramozás

+--------------+ | alkalmazó | +--------------+ |szolgáltatások| +--------------+ | rendszermag | +--------------+ | hardver | +--------------+

+-------------------+ |alk1.| alk.2 |alk3.| +-------------------+ | szolgáltatások | +-------------------+ | rendszermag | +-------------------+ | hardver | +-------------------+

C/ "Alrendszer"

D/ Virtuális gép

+--------------------+ +--------------------+ |a-l-k-a-l-m-a-z-ó-k | |a-l-k-a-l-m-a-z-ó-k | +-----+-----+--+--+--+ +-----+-----+-----+--+ | TSO | DB |X |Y |Z | |ETSS | CMS | TSO |OS| +-----+-----+--+--+--+ +-----+ +-----+ | | OS szolgáltatások | | DOS | | - OS - | +--------------------+ +-----+-----+--------+ | OS Supervisor | | Hipervisor | +--------------------+ +--------------------+ | hardver | | hardver | +--------------------+--------------+--------------------+ E/ Géphálózat +-------------+-------------+-------------+-------------+ | alkalmazók1 | alkalmazók2 | alkalmazók3 | alkalmazók4 | +-------------+-------------+-------------+-------------+ |alrendszerek1|alrendszerek2|alrendszerek3|alrendszerek4| +-------------+-------------+-------------+-------------+ |op. rendsz.1 |op. rendsz.2 |op. rendsz.3 |op. rendsz.4 | +-------------+-------------+-------------+-------------+ | hardver 1 | hardver 2 | hardver 3 | hardver 4 | +-------------+-------------+-------------+-------------+ 5.3. ábra. Számítógépes rendszerek strukturálódása Mint látható, az alrendszeri strukturálódás egyre mélyebbre hatol. Az operációs rendszereket általában speciális szolgáltatásokkal látják el, hogy támogatni tudják alrendszereiket. Emiatt előfordul, hogy a rendszermaghoz is hozzányúlnak egy új alrendszeri interfész kiépítésekor, de ez korántsem okoz akkora problémát, mintha az egész alrendszeri interfészt akarnák bepasszírozni az eredeti operációsrendszeri interfészbe.

5.8. Mintapéldák 5.8.1. Az IBM OS TSO alrendszere Mint korábban már említettük, az IBM cég a TSO alrendszert a TSS időosztásos operációs rendszer ideiglenes kiváltására tervezte. A TSS bukása folytán azonban a TSO végleges megoldássá vált az OS MVT keretén belül. Az OS így legalább egy alrendszer keretéig tud időosztásos szolgáltatásokat nyújtani a terminál-felhasználóknak. Az OS eredeti kötegelt jellege természetesen megmaradt, így az az állapot, hogy a TSO csak alrendszerként szerepel, hátrányokat jelent a kötegelt felhasználókhoz képest. A TSO alrendszerben nincs külön alrendszeri ütemező az időosztásos működés biztosítására, hanem közvetlenül az OS alacsonyszintű ütemezője, a diszpécser oldja meg ezt a taszkok egységes kezelhetősége végett. A konkrét megoldást korábban már emlegettük: a teljes prioritásszám tartományból ki szoktak jelölni egy keskeny intervallumot, amelyen belül a taszkok ütemezéséhez a diszpécser időszeletelési algoritmust használ, az intervallumon kívül esőket pedig prioritásvezérelt alapon ütemezi. A fő probléma ezzel kapcsolatban az, hogy a TSO taszkok nem a legmagasabb prioritásokat kapják, tehát lehet -- és rendszerint szokott is lenni -- olyan kötegelt munka a rendszerben, amelynek nagyobb a prioritása. Az ilyen munkák aztán alaposan megakaszthatják a TSO munkák végrehajtását. A terminálnál ülők csak malmoznak a meg sem moccanó ernyőkép előtt. Mindenesetre a felhasználók a TSO szolgáltatások mellett koránt sem érzik azt, hogy egyedül használják a gépet, amit egy időosztásos környezetben joggal elvárhatnának. Sőt, az a benyomásuk, hogy a gépet valami elűzhetetlen szellemek állandóan "meg-megfogják". A TSO szolgáltatást a felhasználók természetesen parancsnyelven vehetik igénybe. A TSO parancsok vertikalitása azonban még koránt sem olyan erős, mint például a UNIX-é. A várható reakció az, hogy a parancsok paraméterezése bonyolult, amiben örökölte a JCL nyelv e hátrányos tulajdonságát. A dolgon az IBM úgy próbált segíteni, hogy a vertikalitást a parancsokon belül növelte meg. A parancsok jó része olyan, hogy először alparancsokat kell vele aktivizálnunk, és azokat kell tovább paramétereznünk. Ez a hierarchia tulajdonképpen elég kényelmes kezelésmódot ad a kontextusfüggően működő Help (segítségnyújtás) funkcióval együtt, amely utóbbi a meghívásakor mindig az adott alparancs környezetében aktuális segítségszöveget írja ki a terminálra (de többek sajnálatára nagyon tömör yankee nyelven!). Ez annak idején forradalmian új dolog volt, ma viszont egy ilyen Help nélküli szoftvert nem is vesznek igazán komolyan. A TSO interaktív programfejlesztő alrendszer céljára készült. A szolgáltatásait tehát a programozók kiszolgálásához igazították. Ezt mutatja az, hogy az EDIT szövegszerkesztő parancs -- számos alparancsával együtt -- kifejezetten a programírás támogatására van kitanítva. A szövegszerkesztő például ügyelni tud a forrásnyelv szintaxisára, ha jelezzük neki, hogy milyen nyelven írjuk a programot. Sajnos az editor még a régi írógépes terminálokat tételezi fel, ezért sororientált. A mai képernyős terminálokon már nem is szokták használni, hanem valamilyen videoeditorral helyettesítik (pl. a GUTS editorral). A TSO más oldalról azt is hivatott biztosítani, hogy a TSO felhasználó szükség esetén igénybe tudja venni az OS alaprendszer különféle szolgáltatásait is. Ez a SUBMIT parancson keresztül valósítható meg, amivel egy szövegszerkesztővel összeállított munkát (job-ot) fel lehet adni kötegelt feldolgozásra. Az eredményt visszakérhetjük a terminálra. Az ilyen jellegű kapcsolat igénye azzal a következménnyel jár, hogy az interaktív rendszerben az adaterőforrásokkal való gazdálkodást nem választhatjuk meg akárhogyan. Bele kell illeszkedni az OS állománykezelési szisztémájába. Az adatterület allokálás szabályait ezért erősen a kötegelt rendszer követelményei motiválják. A terminálfel-használótól kicsit is bonyolultabb feladat esetén olyan szabályok ismeretét kívánják meg, amelyeket normálisan csak a kötegelt alkalmazónak kell ismernie.

Az interaktivitást a SUBMIT parancs nem biztosítja, az lényegében csak a korábbi RJE távoli kötegelt feldolgozás kiváltását jelenti. A programok interaktív használatát a CALL paranccsal érhetjük el. A CALL paranccsal kérhetjük az OS-t, hogy az aktivizálni kívánt programot töltse be a tárba, és működése közben kapcsoljon össze bennünket a programmal. A TSO parancsnyelv további parancsai rendszerinformációk kilistáztatását, erőforrások (adatállományok, könyvtárak stb.) lefoglalását, hozzárendelését, és segédprogram funkciók végrehajtását teszik lehetővé. Speciális alkalmazása a TSO-nak, hogy a TSO terminálok -- korlátozott jogkörökkel -- operátori konzolként is használhatók. Ezzel a többkonzolos üzemmóddal el lehet kerülni például a rendszerleállítást egy elromlott főkonzol esetén. Más lehetőség, hogy a jelszavakat külön erre a célra rendszeresített konzolon lehet csak beadni, amely ráadásul egy elzárható teremben van (ajtókulcsos védelem). A TSO kulcsszoftverei a következők: * üzenetvezérlő program, ami a távkapcsolatot bonyolítja le a központi gép és a terminálok között; * időosztás-vezérlő taszk (ez maga a TSO), amelyet az operátor indít el, felépíti az időosztásos környezet vezérlőblokkjait, és gondoskodik a TSO-résztvevők taszkjainak indításáról, az ezzel kapcsolatos tárgazdálkodásról (swappinggal ki-be cipel programokat a korlátozott számú aktív területen); * régióvezérlő taszk (RCT) egy adott aktív terület vezérlési feladatainak lebonyolítására (ez például elnyomja, és félreteszi a kiswappolandó taszk függőben lévő B/K igényeit, majd visszahozáskor gondoskodik azok újbóli feladásáról stb.); * LOGON ütemező a terminál-felhasználók előtéri munkáival való kapcsolattartásra (a terminál-kapcsolatot úgy indítja, mintha egy végtelen hosszúságú JOB lenne, és ehhez a JCL kártyákat maga generálja); * terminálmonitor program képezi magát az alrendszeri interfészt, amely a felhasználó parancsainak értelmezésére behívja a megfelelő parancsértelmezőt, és lekezeli a speciális eseményeket (hibákat); * parancsértelmezők a felhasználó üzeneteinek értelmezésére és a kívánt szolgáltatások aktivizálására; * rendszermeghajtó, amely az egész TSO alrendszeri környezet, és az alapoperációs rendszer kapcsolattartását szabályozza, és amelynek paraméterezésével hangolható be a TSO alrendszer az adott installáció speciális igényei szerint. A TSO tehát belülről is elég bonyolult hierarchiát mutat, ami a dinamikus erőforrás-kezelés megvalósításához és a felhasználók minél jobb kiszolgálásához szükséges. A TSO-t, ha nem kértek rendszergeneráláskor automatikus indítást, akkor a rendszeroperátornak kell elindítania. Utána felépül a terminálhálózaton át a terminálkapcsolat, amelynek meglétét a terminál-felhasználók a képernyőn megjelenő üzenetből vehetik észre. Ekkor lehet beadni a LOGON parancsot, melynek paraméterei a bejelentkezési név és jelszó. Bejelentkezés után már működik a Help rendszer, ami a parancsnyelv megtanulását jelentősen megkönnyíti. A TSO parancsnyelv használata ugyan nem sokkal, de könnyíti az OS használatát. A könnyítést azonban még fokozták a TSO-hoz csatlakozó újabb szoftverekkel, amelyek már a képernyős terminálok sajátosságait és a menütechnikát is kihasználták. Ilyen szoftver az SPF (Structured Programming

Facility) és annak továbbfejlesztett, módosított változatai (pl. magyarított UNI).

5.8.2 Nyilvános adatbázis szolgáltatások Az adatbázis--kezelő rendszereket többnyire szintén úgy szokták kiépíteni, hogy azok alrendszert képezzenek. Az adatbázis alkalmazók ugyanis rendszerint elég elhatárolt felhasználói kört jelentenek, többnyire egy szervezet ezzel megbízott ügyintézői tartanak vele kapcsolatot. Ez a feltétel tipikusan olyan, mint amit az alrendszerek kapcsán emlegettünk (szűk alkalmazói körnek kell egyszerűsített szolgáltatásokat nyújtani). A profi adatbázis-kezelő környezetekben van egy szűklétszámú csapat, az adatadminisztrátorok csoportja (ez sokszor egyetlen embert jelent, ami biztonságtechnikai szempontból nem mondható szerencsésnek!). Ez a csoport felelős az adatbázis szerkezeti jellemzőinek kézbentartásáért. A többi alkalmazó ilyen kérdésekbe nem szólhat bele, sőt, nem is ajánlatos, hogy beleszóljon, mert az anarchiához vezetne. Az alrendszeri interfésznek tehát ilyen esetben meg kell akadályoznia azt, hogy az adatbázis szerkezetét illetéktelenek megváltoztathassák. Alapvetően fontos szerep jut tehát a védelmi rendszernek, de ez az erőszakos rendszer a felhasználók érdekeit szolgálja. Ennek egyik tipikus következménye, hogy az alkalmazói programozók csak az adott problémához szükséges adatokhoz férhetnek hozzá az adatbázisból, másokhoz nem. Ez a korlátozásnak tűnő körülmény végeredményben komoly programozási könnyebbséget jelent. A programozónak nem kell terjedelmes adatrekordokból kibogarásznia az algoritmusához szükséges adatokat, mert közvetlenül az algoritmushoz szükséges adatokat kapja kézhez. Kifejezetten a problémára koncentrálhat. Az adatbázis--technika az ügyviteli feldolgozásban jelentős sikereket ért el, különösen a nem számítástechnikai képzettségű alkalmazói körrel tartható jó kapcsolatteremtés tekintetében. Nagyon hatásos eredménye az is, hogy a problémákat adatfüggetlen módon lehet számítástechnikai modellé alakítani, és az adatstruktúrák hatásait ki lehet küszöbölni az algoritmusokból. Ezek persze inkább programozás-technikai tárgyhoz tartozó témakörök. Minket az egészből az érdekel, hogyan szeparálja alkalmas alrendszeri interfészekkel az adatbázis--technika az alkalmazókat: az adatadminisztrátorokat, a programozókat és a végfelhasználókat. Az adatbázis--technika sokáig csak az ügyviteli adatfeldolgozások körében könyvelhetett el magának ilyen sikereket. Kicsit késve, de a mérnöki munkában is teret kapott a bonyolult számítógéppel segített rendszerekben (pl. CAD), amelyekben az egyedileg megoldott részfeladatok algoritmusainak integrálása az egységes interfész hiánya miatt sok gondot okozott a korábbiakban. A helyzeten a műszaki számításokban is csak az egységes interfészt biztosító adatbázis--technika igénybevételével lehetett segíteni. Ezeknek az adatbázis interfészeknek biztosítania kellett, hogy az őket felhasználó mérnököknek, kutatóknak ne kelljen rettenetes mennyiségű számítástechnikai ismeretet elsajátítania ahhoz, hogy használni tudják őket, különben a sutba dobták volna. Manapság az információéhség egyre jobban növekszik, és igen széles néptömegek kezdenek adatbázis szolgáltatások után érdeklődni. Ez a szituáció azt igényelte, hogy az adatbázis--kezelő rendszerek tervezői az ilyen széleskörű alkalmazói körhöz igazodó interfészeket dolgozzanak ki. Ezeket hívják nyilvános adatbázis szolgáltatásoknak. Nyilvános adatbázis szolgáltatásokat ma már otthon, a lakásból, a házi telefonon át igénybe lehet venni, ahol ezek a szolgáltatások már beindultak (a Magyar Posta jóvoltából nálunk is, csak az árfekvés nem tesz lehetővé túl széles alkalmazói kört -- még 2000 tájékán sem!, ZSP,2K.9.24.). A terminálbillentyűzetet --ha nem éppen a telefonkészülékkel, akkor -- valamilyen egyszerű, olcsó eszközzel oldják meg, a megjelenítés pedig a házi TV készüléken történik. Ez nagyon

ökonomikusnak tűnik, de a kapcsolathoz tartozik még egy elég bonyolult vezérlő elektronika is. Ezt azonban általában nem kell megvenni, hanem a postáktól lehet bérelni. A vezérlő elektronika építi fel a kapcsolatot az adatbázissal, amelyből adatokat hívhatunk le, sőt, el is helyezhetünk benne adatokat. A tárolt adatok között szerepelhet például az elektronikus csekkszámlánk, amelynek terhére vásárolni lehet az adatbázisból kiolvasott hirdetések alapján. Franciaországban ilyen nyilvános adatbázisba helyezték el a telefonkönyvet, amelyet ezek után elektronikusan állandóan naprakészen lehet tartani, és ráadásul évente egy kiserdőnyi fát lehet megmenteni azzal, hogy nem kell az egészet könyv alakban megjelentetni. Közben a világháló nálunk is elkezdett tért hódítani, rettenetesen sok információt zúdítva a hétköznapi alkalmazókra. Továbbá segíti őket szinte az élet minden területén. Talán kiegyenlíti a világ gazdaságilag különböző fejlettségű régióiban élő népek lehetőségeit is. Különösen, ha élnek vele! (2001-04-16, ZSP)

5.9. Gyakorlatok 5.9.1.

Mit nevezünk rendszerszolgáltatásoknak?

5.9.2.

Milyen a viszony a rendszerszolgáltatások, a rendszermag és a segédprogramok között?

5.9.3.

Mi a feladata a rendszerolvasónak?

5.9.4.

Hogyan indulnak a rendszerszolgáltatások folyamatai?

5.9.5.

Mit csinál a rendszernyomtató, és honnan veszi a bemenetét?

5.9.6.

Mi a szoftver spooling szerepe a mai operációs rendszerekben?

5.9.7.

Miért kellenek a betöltőprogramok?

5.9.8.

Hogyan történik a programbetöltés?

5.9.9.

Milyenek a fix, és az áthelyezhető programok?

5.9.10.

Miért nem segédprogram a szerkesztőprogram?

5.9.11.

Hogyan indul, és hogyan működik a főütemező?

5.9.12.

Mi a szerepe a közbenső szintű ütemezőnek?

5.9.13.

Mi az alrendszerek feladata?

5.9.14.

Milyen elemekből épül fel egy programfejlesztő alrendszer?

5.9.15.

Milyen feladatokat lát el az IBM JES és a POWER?

5.9.16.

Mi a TSO feladata?

5.9.17.

Hogyan kell a TSO munkát megkezdeni és befejezni?

5.9.18.

Milyen főbb TSO parancsokat ismertünk meg?

5.9.19.

Hogyan lehet TSO alatt ASSEMBLY programokat belőni?

5. A házi TV készüléken keresztül milyen számítógépes szolgáltatásokat vehetünk igénybe?

OS06v21.rtf,2001-04-16,ZSP,végleges

6. BELSŐ ARCHITEKTÚRA

A következő fejezetekben az operációs rendszeri réteghez tartozó szoftver működési és megvalósítási elveivel foglalkozunk. Ahol lehet algoritmus mintapéldákat is adunk. A mintapéldák megértése a PASCAL nyelv elemi ismeretére támaszkodik, de valószínűleg a PASCAL-t nem ismerők is azonnal átlátják az algoritmusok lényegét.

6.1. A rendszermag (kernel) A számítógépes rendszer hierarchikus strukturálódása az operációs rendszeri rétegben tovább folytatódik. A probléma gyökere az, hogy vannak olyan közös rutinok, amelyeket a számítógépes rendszer minden eleme célszerűen közösen használ (az operációs rendszeri réteget megvalósító szoftverrutinok is, természetesen). Minthogy ezekhez minden felhasználónak hozzá kell férnie, csak megfelelően alacsony szinten helyezkedhetnek el. Az operációs rendszeri réteg ennek folytán de facto hierarchikusan strukturált architektúrájú (tehát akkor is, ha eredetileg nem terveztek bele ilyenfajta struktúrát!). A felsőbb szoftverrétegek rutinjai az alsóbb (al)rétegek szolgáltatásaira épülnek. Az operációs rendszeri réteget megvalósító szoftver igen változó méretű szokott lenni az operációs rendszertől elvárt szolgáltatáshalmaz nagyságának függvényében. A bináris programméretek 1 kilobájttól akár több megabájtig terjedhetnek, és emellett igen sok programmodulból tevődhetnek össze. 6.1.1. A rendszermag szerepe Az operációs rendszeri réteg felsőbb rétegeiből intenzíven használt közös rutinokat a rendszermagnak (idegen szavakkal: kernelnek, supervisornak, monitornak, master control programnak stb.) nevezett szoftvermodulba szokták integrálni. Mint látni fogjuk, ez nem egyetlen, összefüggő algoritmusú program. Inkább azt mondhatjuk, hogy kényszerűségből összeötvözött szubrutin- és adattáblázat--együttes, amelynek komponensei azonban ténylegesen csak együttesen képesek a rendszermagtól elvárt szolgáltatásokat nyújtani. A már többször emlegetett, közösen használható rutinok alapvetően kétfélék: * a hardver utasításkészlet bővítményei (melyeket korábban mikroprogramokként emlegettünk); * a hardver sorrendképző (prioritási) és multiprogramozást támogató mechanizmusainak a kiterjesztései. A rendszermagok mérete ugyanúgy erősen változó, mint az operációs rendszereké. Szintén a szolgáltatáshalmaz függvényében 1 kilobájttól akár 1 Mbájtig terjedhet.

A nagyméretű rendszermagok tipikus funkcióhalmaza: * mikroprogramok (nem létező hardverutasítások emulátorai: decimális, lebegőpontos aritmetika stb.); * megszakításkezelés; * hívó- és hívott folyamatok állapotának vezérlése, követése; * folyamat-szinkronizáció; * a védelmi rendszer működtetése; * erőforrás--kezelés; * ütemezések; * eseménystatisztika és -elemzés; * a rendszerkönyvtárak kezelése stb. Ez a felsorolás láthatóan átfedést mutat a 2.1.-ben elemzett rendszeradminisztrációs funkciókkal. A rendszermagot megvalósító szoftverelemek jó része tárrezidens, más része tranziens rutin (tehát csak szükség esetén -- átmenetileg -- kerül be az operatív tárba). Egyes megvalósításokban a tranziens rutinokat szorosan a rendszermaghoz tartozónak veszik. Ennek az az alapja, hogy ezek az operációs rendszerek a hardvererőforrások függvényében konfigurálhatók úgy is, hogy a sűrűn használt tranziens rutinok állandó helyet kapnak az operatív tárban az úgynevezett rezidens területen, akárcsak a rendszermag fixen címzett része (ez a helyzet az IBM 360/370 OS rendszerekben, mint ezt a 2.5.-ben már említettük). Más megvalósítások rendszermagon csak a CPU által állandóan elérhető rutinokat értik. A rendszermag szolgáltatásait megvalósító rutinok -- működésüket tekintve -- két csoportba sorolhatók: * Rendszerprimitívek: rövid, egyszeri lefutású, általában nem megszakítható programok, amelyek igénybevétele során nem keletkezik bejegyzés a rendszernyilvántartásokban; * Folyamatként futó rendszerrutinok: rendszerszubrutinok, melyeket több folyamat szimultán, konkurens módon közösen használ, és amelyek minden megkezdett felhasználása bejegyzést okoz a rendszernyilvántartásokban, nevezetesen: külön folyamatvezérlő blokkot kap. A rendszermag rutinjai -- akár primitívként, akár folyamatként futnak, -- privilegizált üzemmódot igényelnek, hogy más rutinok ne zavarhassák meg véletlenül a működésüket. Ha a hardver több, nem egyenrangú, privilegizált állapottal is rendelkezik, akkor a rendszermag rutinjainak működtetéséhez a legmegfelelőbb privilégiumokat biztosító állapotot kell kiválasztani. 6.1.2. A rendszermag struktúrája A rendszermag strukturálódását több szempont befolyásolja. Ezek közül a leglényegesebbek a védelmi rendszer megszervezésének igényei. Ennek az az oka, hogy a rendszermagon belül -- ahol sajnos a privilegizált állapot miatt "mindent szabad csinálni" -- az egyes rutinokat valahogy egymás ellen is védeni kellene, nehogy szoftverhiba esetén a hibás rutin korlátlanul

"garázdálkodhasson", és óriási károkat okozzon. Sajnos erre a szempontra a korai operációs rendszerekben nem eléggé ügyeltek, ami szoftverhibák javítása ürügyén újabb hibák tömkelegét okozta az újabb és újabb verziókban. (Tipikus példaként mesélik, hogy az IBM OS--ben egy-egy módosításban kb. 3000 hibát próbáltak kijavítani, miközben újabb 2000-t okoztak. Ezért járja a szólás: "Mik az újak egy új operációs rendszeri verzióban?" -- "A hibák!" A felhasználóknak persze csak ezek fájnak.) A korai operációs rendszerek rossz szoftverarchitektúrája miatt volt ilyen nehéz a módosítás. Egy adott ponton végrehajtott változtatás hatása igen sok szinten jelentkezhetett, és az időbeli dinamikát is figyelembe véve az eredmény beláthatatlan volt. Ez ellen hosszas teszteléssel próbáltak védekezni, de hasztalan. A körülmények a matematika indirekt bizonyítási módszeréhez hasonlatosak, ahol már egyetlen ellenpélda is megdönti egy tétel igazságát, hiába sorolunk fel ezer olyan konkrét esetet, amely a tételt nem sérti. A programműködés helyességének bizonyítása sem oldható meg sikeres tesztfutásokkal. A működés helyességének bizonyítására pedig csak akkor lehet egyáltalán vállalkozni, ha minél kisebb önálló részekre tudjuk bontani a vizsgált programcsomagot. A felbontás célja, hogy az egyes rutinok működése minél áttekinthetőbb legyen, és ne függjön össze gátlástalanul minden mindennel. Az egyes modulok között jól rögzített interfészeket kell definiálni, amelyeket nem szabad megkerülni. A rétegzési filozófiát az IBM OS/2 operációs rendszer szoftver-architektúrájának példáján mutatjuk be. Mint már említettük, az OS/2 az INTEL 80286/80386-os mikroprocesszorok hardver-lehetőségeire épül. Ezek a mikroprocesszorok négyszintű privilegizált állapothalmazzal rendelkeznek (l. 1.5.-ben). Az OS/2 architektúrája ennek alapos kihasználásával az alábbi négyrétegű struktúra: +-------------------------------+ | Alkalmazói szint | 3 |-------------------------------| | Parancsértelmező szint | 2 |------------A-P-I--------------| | B/K szint | 1 ^ |-------------------------------| | Kernel | Rendszerhívások szintje | 0 v +-------------------------------+ (API = Application Programming Interface) A rétegek jobb oldalán a 0--3 szintszámok jelzik, hogy az adott réteg melyik hardvervédelmi szintet használhatja. A 0-s védelmi szint biztosítja a legnagyobb privilégiumokat, míg a 3-as szint a processzor nem vezérlő, normál felhasználói állapotát jelenti, amely minden védelmet bekapcsol. A normál állapotban minden védelmi szabály megsértése hardvermegszakítást okoz. A rétegezés célja pont ez: ki akarjuk venni a felhasználó kezéből a "veszélyes" utasítások végrehajtásának jogát azért, hogy a multiprogramozott környezetben "igazságot tudjunk tenni" a futó programok között. Mint látható, a további rétegszinteken az OS/2 saját rutinjai között is szabályozza a privilégiumokat. Még a kernel is két szintet használ: a B/K rutinok kevesebb joggal rendelkeznek, mint az alapvető rendszerhívások. A 2-es parancsértelmező szint felhasználható arra, hogy a profi alkalmazók speciális parancsértelmezőt írhassanak. Ez a parancsértelmező rendelkezik bizonyos privilégiumokkal, de még mindig a kernel ellenőrzése alatt működik, tehát védekezni lehet az esetleges hibás működése ellen. Az OS/2 specialitása, hogy -- vélhetően kifejezetten rendszerprogramozók számára -lehetőséget ad arra is, hogy közvetlen B/K szinten dolgozhassunk. Ez olyan, mintha "le tudnánk szállni" eggyel mélyebb védelmi szintre is, de a valóságban a B/K műveletek védelmi szintszámát emelik magasabbra ideiglenesen. Erre azért van szükség, mert bizonyos perifériák kezelését

máshogyan nem lehet gazdaságosan megoldani (pl. fullscreen videomonitor funkciók). Az OS/2 még ebben a "nagyon veszélyes" állapotban is kézben tudja tartani a dolgokat, hiszen a 0-s szintű rutinok védelmei még mindig működnek. Az OS/2 kernel szolgáltatásai az Alkalmazói programozási interfészen (angol rövidítése: API, l. fentebb) keresztül érhetők el. Azonban nem minden kernelrutin működik hívható szubrutinként. A kernelrutinoknak kell lekezelnie a megszakításokat, vezérelnie kell az OS/2 környezetben futó konkurens folyamatokat stb. A megszakítások időnként nem igazi hibaként lépnek fel, hanem "kiprovokálják" az OS/2 speciális rutinjainak működésbe lépését. Ilyen eset a virtuális tár lapozási igénye, azaz mikor egy program olyan programrészre hivatkozik, amelyik nincs benn a valós operatív tárban. Az OS/2 ezt a hibát megpróbálja elhárítani a hiányzó programrész vagy adat "belapozásával", és ha ez sikerül, akkor újraindítja a programot annál az utasításnál, ahol a szegmenshiba megszakítás jelentkezett. Ezeknek a rutinoknak persze a kernel legalsó rétegében kell elhelyezkedniük, hiszen működésükhöz minden védelmen át kell tudni lépniük. A B/K rutinok működtetését azonban már célszerű bizonyos védelmek fenntartásával végezni, ezért a B/K rutinok magasabb rétegbe kerültek. (A B/K rutinoknak az alacsonyabb szinten lévő zárkezelő rutinokat kell használniuk, amelyről itt csak később lesz szó.) Összességében elmondható, hogy az OS/2 az INTEL hardver igen alapos kihasználásával megkonstruált, korszerű architektúrájú szoftver. (Ez azonban még nem ad neki feltétlen és főleg azonnali piaci sikert!) Az OS/2 négy hardvervédelmi szintre támaszkodhat. Ez nem jelenti azt, hogy belső rétegződésének feltétlen erre a négy szintre kell korlátozódnia. Az egyes védelmi szinteken további finomabb rétegezést is alkalmazni kell az egyes funkciókban kezelt adatstruktúrák védelmére. Az operációs rendszerekben ezért szoftver védelmi szinteket is szervezni szoktak. Ezek működése azon alapul, hogy a kapcsolattartó rutinok betartják az előírt interfész szabályokat. Ez -- emberi tévedések miatt -- tökéletesen nem valósítható meg, tehát a szoftver alapú védelmek sérülékenyek. Korábban, amikor még "elhitték", hogy az operációs rendszeri rutinok nem szegik meg ezeket a szabályokat, csak az alkalmazók elleni védelmek szervezésére koncentráltak. Ma már programhelyesség-bizonyítási módszereket is be lehet vetni a küzdelembe. Használják az adatrejtés módszerét is, amely a magasabb rétegek elől elfedi a rutinok működtetéséhez használt adatszerkezeteket, szemben a korai állapotokkal, amikor a programozók az operációs rendszer ezernyi táblázatában "turkálhattak". Nem kell talán indokolni, mekkora előny, ha tapasztalatlan alkalmazók nem forgathatják fel a rendszer vezérlőadatait. 6.1.3 A T.H.E. architektúra Most bemutatjuk azt az operációs rendszeri architektúrát, amelynek konstrukciós elvei a világon először adtak olyan reményt, hogy azok alapján megbízhatóan működő operációs rendszereket lehet tervezni. A sokat ígérő megoldás Dijkstra-tól származik, és a T.H.E. operációs rendszerről írt cikkében szerepel. A T.H.E. rövidítés a szülőhelynek, a hollandiai Eindhoveni Műszaki Főiskolának nevét takarja. Dijkstra a T.H.E.-ben a következő fő elvet dolgozta ki: Az operációs rendszeri funkciókat jól definiált rétegekbe kell csomagolni, és ezek a rétegek hierarchikusan épüljenek egymásra, tehát a felsőbb rétegek csak az alsóbb szintű rétegek szolgáltatásait vegyék igénybe. Dijkstra másik jelentős eredménye a T.H.E. operációs rendszer kapcsán a csak szekvenciálisan felhasználható erőforrások zármechanizmussal védett használatának megoldása szemaforokkal és szemaforműveletekkel. Ez a szinkronizálás, amiről később bővebben is szó lesz a konkurens

folyamatoknál (l. 12. fejezet). Mint már korábban is szóba került, az operációs rendszer alapvetően kétféle ütemezési feladatot lát el: (1) a CPU ütemezését, azaz megosztását a multiprogramozásban részt vevő programok között (ezt nevezzük CPU multiplexelésnek), és (2) a rendszer összes többi erőforrásának koordinált szétosztását a versengő felhasználók között. Ennek megfelelően az operációs rendszer legmélyebb rétegének minimum egy CPU ütemezőt (alacsony szintű ütemezőt, elterjedt elnevezéssel: diszpécsert) és az erőforrás--gazdálkodáshoz szükséges zármechanizmust kell tartalmaznia. A többi réteg működése ezekre épül. A diszpécser olyan algoritmus, amely a központi feldolgozó egységet (CPU--t) kiveszi az egyik program uralma (angolul: control) alól, és átadja egy másiknak. A diszpécser "vezénylete" alatt működő programok, amelyeket ilyenkor folyamatoknak tekintünk, úgy viselkednek, mint az 1.1.ben már említett, ütemezett párhuzamos (szimultán konkurens, azaz versengő) folyamatok. A diszpécser az ütemezést a felügyelt programok működésére való (bármilyen) tekintet nélkül végzi. A programok nem is avatkozhatnak bele "sorsukba". A legtöbb operációs rendszerben azonban van arra lehetőség, hogy a programok kérhessék működésük felfüggesztését, amíg valami miatt várakozásra kényszerülnek. Nem lenne üdvös ugyanis, ha ilyenkor a program valamilyen CPU-időt pazarló, üres ciklusban "malmozna". Így egy program "eleresztheti" a CPU-t, de maximum ez, amivel az ütemezésbe beleszólhat. A diszpécser többféle ok miatt veheti el a CPU-vezérlés jogát egy futó programtól: * a program, mint említettük, önmaga lemondhat a vezérlés jogáról; * a program B/K műveletet kezdeményez, amire úgyis várni kell; * a megszakítási esemény kiértékelése alapján a működést vissza/át lehet/kell adni valamely korábban megszakított, adott erőforrásra várakozó programnak; * időosztásos üzemmódban lejárt a programnak szánt időszelet. Az ütemezés algoritmusa eseményekhez fűződik, amelyek az előbb említettekhez kapcsolódva az alábbiak lehetnek: * hardvermegszakítások; * "óramegszakítás", mint a CPU időszeletelés lebonyolítását lehetővé tevő speciális hardvermegszakítás; * szoftvermegszakítások, amellyel az operációs rendszeri szolgáltatásokat speciális, megszakítást okozó hardverutasítással lehet igénybe venni; * operátori beavatkozás, ami a kezelőpulton elhelyezett gomb hatására hardver úton aktivizálódik; * terminál-felhasználói kérelem, amit a hardver rendszerint a terminálok ciklikus figyelése alapján vesz észre stb. Az események után a diszpécser mindig körülnéz, hogy el kell-e venni az utoljára futó programtól a vezérlést, és ha igen, ki a következő jogosult (időosztásos vezérlésnél), vagy kinek a munkája sürgősebb (prioritásos vezérlés), akinek oda kell adni a vezérlés jogát. A konkrét algoritmusok persze bonyolultabbak az itt vázoltnál. Ezekről bővebben a 9. fejezetben lesz szó.

A diszpécser a felsőbb szintű ütemezőkkel (l. 4. fejezet) beütemezett munkák folyamatvezérlő blokkjainak (angolul: PCB) várakozó sorát kezeli. A programot a diszpécser felé egy PCB képvisel, amelyben a program megszakítási állapotvektora, üzemi állapota, folyamatazonosítója és más jellemzői szerepelnek. A zármechanizmus (mint említettük), a CPU-n kívüli többi számítógépes erőforrásokra vonatkozó felhasználási igények sorba állításának (szekvencializálásának) eszköze. A zármechanizmus a programok megbízásából hol megszerez (lezárás), hol szabaddá tesz (felszabadítás) bizonyos erőforrásokat. A zármechanizmusok működéséhez igen erős privilégiumokra van szükség. Működésük közben le kell tiltani még a megszakításokat is, mert egy alkalmatlan időpontban érkező megszakítás kritikus helyzetet teremthet. A 12. fejezetben erről még részletesebben lesz szó. A fentiekből azonban világos, hogy a zármechanizmus rutinjainak a rendszermag legalsó, legtöbb privilégiummal rendelkező rétegében kell elhelyezkedniük. A kritikus helyzet szemléltetésére bemutatunk egy tárfoglalási szituációt. Tegyük fel, hogy számítógépes rendszerünkben két CPU van, amelyek közös operatív táron osztozkodnak. A két processzoron természetesen izokron folyamatként párhuzamosan futhat két program. Tegyük fel, hogy mindkettő éppen tárigényt jelent be. Az 1. CPU-n futó program mondjuk 20 Kbájtot, a 2. processzoron futó pedig 32 kilobájtot kér. A két processzort közös operációs rendszerrel üzemeltetjük, ami azt jelenti, hogy a tárkezelés mindkét program számára közös. Mindkettő ugyanazt a tárfoglalási kódot fogja aktivizálni. A kód (amely az operációs rendszerekben feltétlenül megosztható szokott lenni) a két processzoron (izokron módon) nagyjából egyformán halad. Az egyik ponton a tárkezelő előveszi a szabad tármezőre vonatkozó adatokat a rendszertáblázatokból, hogy megnézze, honnan elégíthető ki a kért tárigény. A lefoglaláshoz ezután módosítania kell a vonatkozó táblázatok adatait. Amíg az egyik gépen futó tárfoglaló folyamat ezt végzi, addig a másiknak nem szabad hozzá sem nyúlnia a táblázathoz, mert esetleg félig aktualizált adatok alapján kezdene dönteni arról, hogy hol foglaljon le tármezőt a hívó program számára. Az különösen nagy zavart okozna, ha a két tárfoglaló folyamat egyidejűleg kezdené módosítani ugyanazokat a táblázati adatokat. A probléma megoldására a szabadhely táblázatokhoz való hozzáférést zárral védeni kell. Ha például az 1. gépen futó tárfoglaló folyamat ér előbb a táblázatok elővételéhez, akkor a zárat le kell zárnia, és egészen addig zárva kell tartania, amíg az összes szükséges módosítást végre nem hajtotta a táblázatokon. A 2. gépen futó tárfoglaló folyamat ily módon észreveheti, hogy a táblázatok foglaltak, és várakozik, amíg a zár ki nem nyílik. Az algoritmusok ilyen szakaszait kritikus szakaszoknak nevezik. A zárakat Dijkstra szemaforok alkalmazásával oldotta meg, amelyekre két műveletet vezetett be, a P és V műveletet. (A P és V két vonatkozó holland szó kezdőbetűje.) Szemafor legegyszerűbben bináris változóként valósítható meg (a neve legyen S), amely tehát két értéket, 0-t vagy 1-et vehet fel. Jelentse az 1-es a szabad (zöld) jelet, a 0 pedig a tilos (piros) jelet (közlekedési jelzőlámpáktól vett analógiával). Amikor egy program egy szemaforral védett erőforráshoz akar hozzáférni, akkor egy P(S) művelettel a szemafort (amelynek kezdeti értéke 1, vagyis szabad, zöld volt) átállítja 0-ra, azaz tilosra (pirosra), jelezve, hogy az erőforrás le van foglalva. A P műveletet vagy úgy programozzák, hogy addig nem hajtódik végre teljesen, amíg a szemafort valaki vissza nem állítja szabadra; vagy úgy, hogy visszaad egy válaszkódot, hogy sikerült-e a foglalás. Az utóbbi esetben a programnak addig kell ciklusban várakoznia, amíg a foglalás nem sikerül. A zárat a V(S) művelettel lehet kinyitni, esetünkben S-nek az 1-re (szabadra, zöldre) állításával, jelezve, hogy az erőforrás már szabad. Ezt a felszabadítást a lehető leggyorsabban végre is kell hajtani. A zárral védett erőforrásokat csak a kritikus szakaszon illik zárva tartani, mert különben túl sok felesleges várakozás léphet fel.

A szemaforokat a gyakorlatban nem bináris, hanem többnyire egész változókkal szokták megvalósítani. Ennek oka részben az inkrementáló/dekrementáló hardver utasítások elterjedt használatában, részben az általánosíthatóság lehetőségében keresendő. Vannak ugyanis olyan erőforrások a számítógépes rendszerben, amelyből esetleg egynél több is van, vagy korlátozott számban használható egyidejűleg. Ilyenkor a zárat csak akkor kell bezárni, ha a felső korlát kimerült. Ez egész értékekkel való számlálgatással figyelhető meg. A XENIX operációs rendszerben az alkalmazói programokban néhány szemaforokkal foglalkozó rendszerhívás alkalmazásával lehet zárakat használni. Magát a szemafort érdekes módon egy speciális állományként (szemaforállomány) valósítják meg. Az operációs rendszer a szabad/tilos információt a szemaforok állományleírásában helyezi el a megfelelő szemaforműveletek hatására. E módszer előnye, hogy független, de együttműködő programok erőforrás-kezelése is szinkronizálható ilyen zárak alkalmazásával. Ezt a példát csak azért említettük, hogy rámutassunk a szemafor elv általános céljára, és konkrét megvalósításának igen eltérő lehetőségeire. A megvalósítás módját befolyásolja, hogy milyen sebességgel kell "kapcsolnia" a szemafornak, és hogyan tudnak hozzáférni az erőforrásért versengők a szemafor állapotához. A továbbiakban betekintünk a T.H.E. architektúra rétegeibe, amelyeket a 6.1. ábrán mutatunk be. +-------+-------------+--------------------------------+ | Szint | Főfunkció | Alfunkciók | +-------+-------------+--------------------------------+ | | | | | 4. | JOB-kezelők | 1. Felhasználói folyamatok | | | | 2. Vezérlőáram--olvasó | | | | | |-------|-------------|--------------------------------| | | | | | 3. | Berendezés- | 1. Logikai/fizikai B/K | | | kezelők | 2. Pufferkezelés | | | | | |-------|-------------|--------------------------------| | | | | | 2. | Operátori | 1. Operátori kommunikáció | | | interfész | 2. Vezérlőpult--kezelés | | | | | |-------|-------------|--------------------------------| | | | | | 1. | Lapkezelő | 1. Tárkezelés | | | | 2. Virtuális tár | | | | | |-------|-------------|--------------------------------| | | | | | 0. | Mag | 1. Folyamatvezérlés | | | | 2. Szinkronizálás (zárkezelés) | | | | | +-------+-------------+--------------------------------+ 6.1. ábra. A T.H.E. architektúra rétegei. A T.H.E. operációs rendszer ötrétegű struktúrát mutat (az egyes rétegeket a 0-tól 4-ig terjedő szintszámok kódolják). A rendszermagot az alsó négy szint képezi, jóllehet a legalsó, 0. szint is a megtévesztő Mag elnevezést kapta.

A T.H.E. architektúrában a tárkezelés az 1-es szinten található. Az 1-es szint -- a helyes struktúrára adott alapelvünk szerint -- csak a 0. szint szolgáltatásait használhatja. Ugyanakkor a 0. szint egyedül önmagát hívhatja csak. Ebből az egyszerű tényből következik, hogy a 0. szintű rutinoknak abszolút tárrezidenseknek kell lenniük. Ha tranziens rutinokat is használnának, akkor azoknak tárat kellene igényelni a betöltés előtt, ami az eggyel magasabb rétegben elhelyezkedő tárkezelő szolgáltatásainak igénybevételét eredményezné. Ez sérti a struktúrára vonatkozó alapelvünket. (A Mag elnevezés tehát itt főként a 0. szint rezidens tulajdonságára utal.) Még egy érdekes következmény, hogy mivel a folyamatvezérlés a 0. szinten található, a magasabb rétegek rutinjait akár primitívként, akár folyamatként is meg lehet valósítani, hiszen folyamatvezérlési szolgáltatásra mindegyik támaszkodhat szükség esetén. A 0. szintű rutinok viszont többnyire megszakíthatatlanul, primitív műveletként futnak. Az 1-es szinten futó tárkezelő a T.H.E. architektúrában például folyamatként fut, és működéséhez használja a 0. szintű P és V zárkezelő primitíveket. A T.H.E. architektúra 2-es szintjének feladata az operátori kommunikáció támogatása. Ha megfigyeljük, ez a körülmény az egyébként szintén perifériának minősülő operátori konzolnak kiemelt kezelést biztosít. Ehhez tudni kell, hogy a T.H.E. operációs rendszer tipikus kötegelt rendszer, amelyben persze az üzemeltető személyzetnek jelentős szerepet szántak. Több érdekes következménye van annak, hogy a 2-es szintet az operátori interfésznek szánták. Mivel a perifériakezelés eggyel magasabb rétegben van, az operátori konzol kezelését a rétegen belül külön kellett megoldani. Ez némi redundanciát jelent, de mondhatnánk erre azt is, hogy elvtelen kompromisszum. (Mellesleg vegyük észre, hogy ugyanez a helyzet az 1-es szintű Lapkezelés virtuális tárkezelőjével is.) A magasabb rétegek rutinjai ezzel szemben igénybe tudtak venni operátorkonzol--szolgáltatásokat. Az operátori interfészt úgy programozták, hogy a valós konzolt virtuális konzolokra ossza fel, és az összes szolgáltatást kérő úgy érezhette, hogy neki külön operátori konzol áll a rendelkezésére. Ez akár az egyes perifériakezelő rutinok folyamataira is igaz volt, amit elég jól ki lehetett használni. A valódi konzolt lekötés/felszabadítás műveletpárral lehetett birtokba venni. A 2-es szinttől felfelé található rutinoknak már nem kellett feltétlen tárrezidensnek lenniük, hiszen betöltésükhöz igénybe lehet venni az alacsonyabb szintű Lapkezelő szolgáltatásait. A 3-as szinten elhelyezkedő Berendezéskezelők biztosítják a magasabb rétegeknek a B/K szolgáltatásokat. Ezek a T.H.E.-ben ütemezett folyamatokként futnak. Használhatják az alsóbb szintek összes szolgáltatását. Így például a B/K hibák kezelésére virtuáliskonzol--szolgáltatásokat kérhetnek a 2-es szinttől, tárigényt jelenthetnek be az 1-es szintnek az átviteli pufferek lefoglalására, és 0. szintű zármechanizmust használhatnak az ütköző B/K igények szinkronizálására. A T.H.E. architektúra legfelső, 4-es szintjén találjuk a rendszerfolyamatokat (vezérlőáram-olvasó) és az alkalmazói folyamatokat (munkákat). A vezérlőáram-olvasó gondoskodik a munkák (JOB-ok) felvételéről és indításáról, ahogy erről már a 4.10.-ben már szó volt. A munkákból létrejövő folyamatok csak az alsóbb rétegekbe csomagolt funkciók szolgáltatásainak igénybevételével jutnak hozzá a kívánt erőforrásokhoz. A rétegek interfészein át azonban a látható erőforrások gyökeresen eltérhetnek a fizikailag létező eredeti erőforrásoktól. Ezek közül példaként a virtuális tárat és a virtuális konzolt említhetjük a T.H.E. kapcsán. A rendszerfunkciók szigorúan vett hierarchikus strukturálása számos előnnyel jár az operációs rendszerek fejlesztésekor. Elvileg lehetséges az egyes rétegek független fejlesztése az előírt interfészek rögzítése után. Így kisebb modulok belövését kell végezni, és programhelyességvizsgálatok is használhatók.

A T.H.E. architektúrából talán nem azonnal világos, de a rétegekkel kapcsolatban fontos követelmény, hogy az egyes rétegek funkcióinak megvalósításához szükséges táblázatokat, adatszerkezeteket egymás elől el kell zárni, ha a hierarchiát komolyan gondoljuk. Ez a stukturált programozásban emlegetett adatrejtés módszerével érhető el. Ehhez ma a legjobb nyelvi eszközöket talán a C programozási nyelv biztosítja. A T.H.E. architektúra tervezési elveit még egyszer összefoglaljuk: * Minden szint úgy kezeli a közvetlenül alatta levő szintet, mintha huzalozott (hardwired), invariáns funkció lenne, amely mereven rögzített interfészeken keresztül érhető el. * Mindegyik szintnek csak a közvetlenül alatta levő szinthez van direkt elérése, és a mélyebb szintekről nincs tudomása. * Az információ "elrejtése" tökéletes annyiban, hogy egy adott szint számára ismeretes adatstruktúrákat csak azon a szinten lehet kezelni. Valamely szinten levő adatokra vonatkozó funkciót csak az adott szint valósít meg. Így például a kipakoló rutin semmit sem tud a pufferolásról, de a pufferkezelő sem tud semmit a berendezésekről stb. A szigorú hierarchia, és a funkciók rétegekbe csomagolása persze csak közelítésekkel és kompromisszumokkal valósítható meg. Abban az operációs rendszerek tervezői mindenesetre egyetértenek, hogy törekedni kell a hierarchikus rétegelésre. A T.H.E. architektúra 1-es és 2-es szintjéről már említettük, hogy "inognak" a majdnem elvtelen kompromisszumok miatt. A konzol kiemelt kezelésével kapcsolatban az igazság kedvéért meg kell jegyezni, hogy a konzolt szinte minden operációs rendszerben kiemelten kezelik (jellemző "kórtünet"). A T.H.E. esetében a virtuális konzol elv bevezetésének igénye érthetőbbé válik, ha figyelembe vesszük, hogy akkoriban terminálok még nem voltak. Így a virtuális konzol az interaktív eszközök irányába tett progresszív törekvésként értékelhető. Ami a virtuális tárkezelést illeti, más operációs rendszerekben is előfordul külön B/K kezelő a virtuális tár háttértárának kezelésére. A T.H.E. alapját képező hardverben kimondottan erre a célra szentelt mágnesdobot alkalmaztak virtuális háttértárnak, amelynek extra kezelése ezért nem volt olyan nagy probléma. Megjegyezzük még, hogy az operációs rendszerek legerősebb struktúraromboló képződménye a megszakításkezelés. A megszakítás-kezelők ugyanis előszeretettel igénylik a különböző rétegekbe rejtett táblázatokhoz való hozzáférést. 6.1.4. A szolgáltatáskérések formái A 2. fejezetben említettük, hogy alacsony és magas szintű rendszerszolgáltatások vannak. A magas szintű szolgáltatásokat részben a rendszermaghoz csatlakozó rendszerfolyamatok (vezérlő-áram-olvasó, főütemező, listázóprogram, iniciátorok és terminátorok stb.), részben a rendszerközeli szoftver (segédprogramok, angolul: utilities) biztosítják. A rendszerfolyamatokat a 4.10.-ben tárgyaltuk, most részletesebben a rendszerközeli szoftverre térünk ki. A rendszerközeli szoftver olyan általánosan használható programok halmaza, amelyet általában az operációs rendszer, mint szoftvercsomag részeként szállítanak. Ezért "gyári szoftvernek" is nevezik. Ezek a programok egyszerűen és jól paraméterezhetők, és így idomíthatók konkrét adatfeldolgozási feladatokhoz. A következő főbb funkciókat szokták megvalósítani: * állománymentő és visszaállító programok adat- és rendszervédelmi feladatokhoz;

* állománymásoló és -konvertáló programok; * rendszerkatalógusok karbantartását és listázását végző programok; * program- és adatkönyvtárak kezelésére szakosodott programok; * rendező-, össze- és szétválogató programok; * alacsony szintű operációs rendszeri szolgáltatások ellenőrzött és rendszabályozott elérése magas szintű interfészen át (például: jelszómódosítás, hozzáférési jogkörök változtatása stb.); * szövegszerkesztők (editorok), amelyek a terminálok megjelenésével váltak döntő fontosságúvá; * egyéb, univerzálisan használható program(csomag)ok. Minthogy ezek a segédprogramok a rendszermagnak csak a felhasználói, itt részleteiben most nem velük, hanem inkább az alacsony szintű interfésszel foglalkozunk. Az alacsony szintű szolgáltatásokat nem a végfelhasználók, hanem a szoftverfejlesztők, a programozók használják (illetve munkájuk eredményeként azok a programok, amiket megírnak). Az alacsony szintű szolgáltatásokat csak programokból lehet igénybe venni. Az igénybevétel módját rendszerhívásoknak nevezzük. Ezek -- lényegüket tekintve -- eljáráshívások, de az eljárások törzse a rendszermagban helyezkedik el, és ezért privilegizált üzemmódban dolgozhat. A hívások megvalósítási módja programnyelvenként változhat. A magas szintű programozási nyelvekben olykor a normál eljárások hívásával azonos előírások szerint lehet őket kódolni, de elterjedtebb az, hogy a rendszerhívások módja eltérő, és egyes hívások implicit módon hajtódnak végre egyes programnyelvi objektumok hatására (például: OPEN, CLOSE stb.). Az alacsony szintű programozási nyelvekben a rendszerhívás erősen eltér a normál eljárások hívásától. A rendszerhívásokhoz más hardver gépi utasítást kell használni, mint a normál szubrutinhívásokhoz. Ennek oka a tárvédelemben keresendő. A normál programnak a rendszermag területére tilos belépnie. Ez a tiltás csak úgy oldható fel, ha van olyan hardverutasítás, amely a processzort átlendíti vezérlőmódba. A megoldás a már többször említett szoftver megszakító utasítás (l. 2.2.). A helyzet az, hogy akár alacsony szintű, akár magas szintű nyelven programozunk, a lefordított, összeszerkesztett, futóképes programok végső fokon mind a szoftver megszakító utasításra támaszkodnak. A szoftver megszakító utasítás behívását a magas szintű nyelvekben a fordítóprogramok, alacsony szintű programokban pedig az úgynevezett makrohívások szervezik meg. Korábban a rendszerhívások közvetlenül csak alacsony szintű nyelveken voltak elérhetők. Ehhez hozzátartozik, hogy a rendszerhívások módját alapvetően az alacsony szintű programozáshoz optimalizálták. A fejlődés azonban abba az irányba mutat, hogy a rendszerhívásokat a magas szintű programozási nyelvek igényeihez illesszék inkább. Egészen másképpen szokták programozni ugyanis a rendszerhívásokat assembly szinten, és a magas szintű nyelvek fordítóprogramjaihoz. Az assembly programozásban a paraméterek átadása túlnyomórészt a CPU különböző regisztereit használjuk. Erre azért van lehetőség, mert egy assembly programban mindig pontosan előre ismerjük, hogy hány és milyen paramétert kell átadni a hívott rutinnak. A programozó ezeket egyszerűen kiosztja a rendelkezésre álló regiszterek között. Ez jó is neki, mert át tudja látni a helyzetet, tudja, miben, mit találhat meg. Ugyanakkor a fordítóprogramok írói a szubrutinhívásokat általános elvek szerint szervezik meg, hiszen előre nem lehet tudni, hogy hány

és milyen paramétert kezelő szubrutin fordul majd elő a programban. Ennek egyik megoldása, hogy a behívott szubrutin kap egy mutatót (például egy egyezményes CPU regiszteren át), és ez a mutató a paramétereket leíró táblázat elejére mutat. A másik módszer, ami a legújabb hardverarchitektúrákban szinte kizárólagos, hogy a hívási paramétereket veremtárba helyezik, és a hívó szubrutinnak onnan kell azokat elővennie. Az utóbbi a legkompaktabb paraméterhívási módszer. Az operációs rendszer akkor támogatja jobban a magas szintű nyelvi hívásokat, hogyha a paraméter-átvételt ezek igényei szerint szervezi. Az MS--DOS-ban az INT 21H, szoftvermegszakításokra alapított rendszerhívási szisztémát lehet használni. A paraméterek átadása az AX és BX CPU regisztereken keresztül történik. Az OS/2-ben a hívási paramétereket a veremtárba kell helyezni, a rendszerrutin onnan fogja őket felszedni azokba a regiszterekbe, amelyikbe éppen neki tetszik. A rendszerhívás az OS/2-ben makroutasítással történik. Ha az OS/2-ben egy magas szintű programban akarunk lezárni egy állományt, a fordítóprogram pontosan ugyanolyan kódkifejtést generál, mint amit az alább vázolt OS/2 hívási példa mutat. A megoldás "öszvér jellegű", mert a hibakódot az OS/2 is az AX regiszterben adja vissza, és nem a veremtáron át kapjuk meg. Az OS/2-ben ennek MS--DOS kompatibilitást biztosító szerepe van, de egyetlen, fix CPU regiszteren át érkező információt a fordítóprogramok is előnyösen tudnak hasznosítani. Példaként elemezzük az MS--DOS és az OS/2 assembly nyelvű állományzáró (CLOSE) rendszerhívást: MS--DOS: mov ax,1000h ; funkciókód--paraméter mov bx,fhandle ; "file handle" paraméter int 21h ; rendszerhívás ; szofvermegszakítással or ax,ax ; hiba volt? jnz hibakez ; igen! OS/2: push call or jnz

fhandle DosClose ax,ax hibakez

; ; ; ;

"file handle" paraméter rendszerhívás hiba volt? igen!

A rendszerhívások igen szerteágazóak; ahány rendszermag, annyi szokás. A zűrzavar talán még a hardver--utasításkészletekben mutatkozó eltéréseket is meghaladja. Igen kevés remény van valamelyes tipizálásra. A hívások egy része primitívként, más része folyamatként fut. Eltérőek lehetnek a számukra biztosított privilégiumok is. Ezek befolyásolhatják a behívás módját. Már említettük, hogy a CPU, mint erőforrás többnyire csak elereszthető egy programból. Ezért a programoknak biztosított CPU-idő erőforrással kapcsolatos szolgáltatások listája néhány várakozási igényt bejelentő rendszerhívásból áll. Például a WAIT a határozatlan, a SLEEP pedig a határozott ideig való várakoztatásra szolgál. A normál programoknak nem áll rendelkezésre az a funkció, amely a várakozások feloldásához szükséges. Erre használják az AWAKE hívást, amely értesíti a diszpécsert, hogy valamelyik rutint "fel kell ébreszteni". A következő fontos erőforrás az operatív tár vagy az esetleg létező virtuális tár. A tárkezelő funkciók közül a két legfontosabb rutin a: * GETMAIN(tárigény) a tárigények bejelentésére és a

* FREEMAIN(tárméret) a tárlekötések felszabadítására. A kívánt tárméreten kívül alkalmasint más paraméterek is felmerülhetnek, különösen virtuális tárkezelésnél. A FREEMAIN-ben például azt is nyilvánvalóan meg kell adni, hogy melyik korábbi foglalást akarjuk lemondani. A rendszerhívási funkciókat alapvetően két nagy csoportba soroljuk: rendszeradminisztrációs rutinok és B/K rutinokra. Ezeket az operációs rendszerek általában erősen megkülönböztetik. A rendszeradminisztrációs rutinok a kernel mélyebb rétegeiben lévő funkciók igénybevételét teszik lehetővé. A B/K funkciók rendszerint maguk is igénybe veszik ezeket a szolgáltatásokat, ezért kell őket mélyebb rétegben elhelyezni. Minthogy ezek a legkevésbé tipizálhatók, itt nem foglalkozunk velük részletesen, hanem a 7. fejezetben adunk rájuk példákat. A B/K rutinokat rendszerint még további osztályokba sorolják. A besorolási szempont szintén operációs rendszerenként változik. Alapvetően megkülönböztetnek fizikai és logikai adatkezelő rutinokat. A fizikai rutinok a perifériák közvetlen kezelésére szakosodott funkciók programjai, amelyeket periféria meghajtóknak is neveznek. A logikai adatkezelési funkciók pufferelési technikával (átmeneti tármezők alkalmazásával) oldják meg a fizikai berendezésen előírt adatszerkezet és az alkalmazási programban feltételezett adatstruktúra közötti konverziót. További osztályozás tárgyát képezik a támogatott logikai adatszerkezet--típusok elérési módjait biztosító funkciók. Ezek az úgynevezett adatelérési módszerek (szekvenciális, random, indexelt szekvenciális, invertált, láncolt stb.). Az 1.4.-ben említettük, hogy a perifériák alapvetően kétfélék lehetnek: blokk típusúak és karakter típusúak. A perifériameghajtók ennek megfelelően szintén két osztályba sorolhatók. A blokk típusú kezelők arra készülnek fel, hogy az adatokat csak nagyobb egységekben, adatblokkok formájában lehet átvinni a periféria és a tár között. A tipikus méretek 16 bájttól 32 kilobájtig terjedhetnek. Az átvitel meglehetősen nagy sebességű, több Mbájt/sec értéket is elérhet. Ezért ezeket a meghajtókat nevezik gyorsperiféria meghajtóknak is. A gyors perifériák emellett speciális B/K csatornákon át érhetők el, amelyek működése a CPU-tól függetlenül vezérelhető, emiatt független ütemezésre szorul. A karakter típusú meghajtók szerepe az, hogy a multiplex csatornán különböző perifériákról érkező lassú, karakterenkénti átviteleket demultiplexelje, azaz szétválogassa felhasználók szerint illetve -- ellenkező irányban -- eljuttassa a kívánt perifériához. (A multiplex csatornában azért keverednek a különböző perifériák adatai, mert ezekhez a lassú átvitelekhez nem lenne gazdaságos külön adatcsatornákat alkalmazni. A hardvercsatornán emiatt az adatok mellett az elérendő periféria címét is mindig át kell küldeni.) A fizikai szintű kezelőknek az a feladata, hogy a logikai szintű rutinok felé eltüntessék a blokktípusú és karaktertípusú átviteli sajátosságokat. Ehhez pufferelési technikát kell használni. A logikai adatkezelés, miután a perifériák fizikai sajátosságait puffereléssel eltüntettük, kétféle lehet: * blokk szintű adatelérés, és * rekord szintű adatelérés. A blokk szintű adatelérésnél a logikai adatszerkezettől valamelyest független, tőle eltérő méretű pufferekben tárolt adatokkal dolgozunk. Ennek szerepe az átvitel gyorsítása. A logikai adategységekben történő átvitel azért lassúbb, mert az adatblokkban elférő rekordokat egyenként viszi át, ami mindenképpen plusz adminisztrációs időt jelent. A szokásosan használt rendszerhívás

neve után ezt READ/WRITE szintnek nevezik. A READ/WRITE szintet a következő funkcióhalmazzal szokták támogatni: * ASSIGN, OPEN: a fizikai és logikai állományok összerendelésére és az adatátvitel előkészítésére, amely egy sereg operációs rendszeri táblázat létrehozását eredményezi; * CREATE: egy még nem létező fizikai állomány létesítésére, amelynek adatai bekerülnek a különféle katalógusokba (nem minden operációs rendszerben van ilyen rutin explicit módon); az állományt egyben meg is nyitja, de abba csak írni lehet; * READ: egy adatblokk olvasására szolgáló funkció; * WRITE: egy adatblokk írására szolgáló funkció; * REWRITE, UPDATE: ha van ilyen funkció, akkor a korábban beolvasott és közben módosított blokk visszaírására szolgál; * SEEK: pozicionálás az adatállományban egy adott című vagy sorszámú blokkra; * CLOSE, UNASSIGN: egy adatállomány lezárása. A rekord szintű elérés igazodik az alkalmazásban használt rekordszerkezethez. Ezt az általánosan használt rutinnevek miatt PUT/GET szintnek is nevezik. Az eléréshez használt makronevek nem feltétlen különböznek a READ/WRITE szintnél ismertetett készlettől, csak a READ helyett kell GET, a WRITE helyett PUT makrohívást használni. A makrók paraméterezése persze eltérő. A rekord szintű elérés elsősorban arra hivatott, hogy a különböző adatelérési módszereket támogassa, bár a blokk szintű elérésnél is használnak eltérő adatelérési módokat. A választandó adatelérési módszert OPEN időben kell meghatározni. A READ/WRITE és PUT/GET utasítások paraméterezésére az elérési módszer kevésbé szokott kihatni, amellyel a programok többé-kevésbé adatelérési módszertől független programozását igyekeznek biztosítani. Az adatok szervezésének változása esetén emiatt nem kell módosítani a programot. Ez persze csak akkor működik, ha az adatszervezésre vonatkozó információ a programon kívülről érkezik. Ez a helyzet például az IBM OS-ben, ahol ezt az adatot a vezérlőáram DD adatleíró parancsában adhatjuk meg. Az adatkezelés és a B/K programozás további részleteit meghagyjuk az adatkezeléssel foglalkozó szakirodalomnak.

6.2. Megszakításkezelés A megszakításokról a hardvertulajdonságok elemzésénél már volt szó (l. 1.4.). Most rámutatunk arra, hogy a megszakításokat kezelő -- elterjedt szakzsargonban "lekezelő" -- rutinoknak mindig a rendszermagban kell elhelyezkedniük, továbbá elemezzük vázlatos algoritmusaikat. A megszakítások során a hardver valamelyik szintű vezérlőállapotába kerül át (ha van ilyen megkülönböztetett állapota). Ez azt jelenti, hogy a megszakítás után induló kód privilegizált jogokkal rendelkezik. Minthogy a privilégiumokat egyedül az operációs rendszernek szeretnénk biztosítani, a megszakítás-kezelő rutinoknak feltétlen az operációs rendszerben kell lenniük. Tovább fontos, hogy a megszakítás-kezelők gyorsan reagáljanak a megszakítási eseményekre. Emiatt a legalapvetőbb kezelő rutinoknak feltétlen tárrezidenseknek kell lenniük. Ezekből a feltételekből következik, hogy a megszakítás-kezelők az operációs rendszerek magjában helyezkednek el (ezt az

állításunkat később még pontosítjuk). A belépés a rendszermagba (védelmi rendszerrel rendelkező hardver esetén) csak a megszakításkezelőkön keresztül érhető el. Ezután a rendszermag -- erősen hardverfüggő módon -- reagál a belépésre. Példákat az 1.4.-ben és 1.5.-ben elemeztünk. Megjegyezzük, hogy a rendszermagba való belépést olyan hardvereknél is a megszakításokon keresztül szervezik, amelyekben nincs védelmi rendszer, úgyhogy ez a rendszerrutin-hívási mód igen széles körben elterjedt. A védelmi rendszerrel nem rendelkező hardverekben a rendszermag-funkciók elvileg egyszerű szubrutinhívással is elérhetők lennének, de akkor ismerni kellene a tárban elfoglalt pontos helyüket. Néhány hardvernél ez a feltétel teljesül (például a ROM-ba égetett rutinok esetében), de az operációs rendszerek módosítgatása során a rutincímek óhatatlanul eltolódnak. Az összes program, amelyik konkrét címre hivatkozik, az új operációs rendszeri verzió felügyelete alatt működésképtelenné válna. A megszakítások, mint azt az 1.4.-ben is elemezzük, ugrótábla alapján érik el a kezelőrutinokat. Ha tehát egy rendszerfunkció hívását valamelyik megszakításra alapozottan kezeljük, akkor programjaink mindig működőképesek maradnak, mert a hardver a megszakító rutin indítását -- a szoftvertől függetlenül -- mindig ugyanarról a vektorcímről indítja. Az operációs rendszer módosításakor csak arról kell gondoskodni, hogy a megszakítási vektorba a kezelőrutin új címe kerüljön. A védelmi rendszer hiánya folytán a vektorcímet a felhasználói programból meg lehet változtatni. Ezzel a módszerrel "el lehet kapni" a rendszertől a megszakításkezelést. A személyi számítógépek körében előszeretettel használják ezt a módszert -- főként tárrezidens és a kikapcsolás ellen védekező vagy a képernyőt és billentyűzetet különlegesen kezelő, például játékprogramok esetében. Minthogy itt monoprogramozott rendszerekről van szó, a felhasználó legfeljebb magának okoz gondokat hibás megszakítás-kezelő program bekapcsolása esetén. Multiprogramozott környezetben viszont az ilyen hiba elviselhetetlen következményekkel járhat. A megszakításkezelés elvei megkövetelik, hogy minden, a hardver számára megkülönböztethető, megszakítási típushoz tartalmazzon a rendszermag egy első szintű megszakítás-kezelőt (angol rövidítéssel: FLIH = First Level Interrupt Handler). Pontosabban tehát ez az a megszakító rutin, amelynek mindig tárrezidensnek kell lennie. Az FLIH rutin hiányozhat, ha az adott konfigurációban a megfelelő megszakítástípus soha nem fordulhat elő, de a géphiba miatti "tévelygések" elkerülésére ilyenkor is szoktak használni valamilyen "csontváz" kezelőrutint. Egy FLIH rutinnak, ha megszakítás folytán megkapja a vezérlést, legfontosabb dolga, hogy azonnal letiltsa a működését induláskor zavaró -- legalább a saját típusába tartozó -- megszakításokat. Ezt addig kell fenntartani, amíg a megszakított program folytatásához szükséges adatokat, az 1.4.ben említett állapotvektort, el nem tárolta az operációs rendszer megfelelő táblázataiban. Ezzel biztosítható a procesz-szorállapot visszaállíthatósága és a program későbbi folytatása (ha erre szükség van). A megszakítás-kezelőknél ezen a "kritikus szakaszon" kell fenntartani a megszakítások tiltását. Amint a megszakító rutin túljut egy adott megszakítási osztályra vonatkozó kritikus szakaszon, a megszakítást azonnal fel kell szabadítani, hogy ne legyen túl hosszú időre elvágva a rendszer a külvilág eseményeitől. Kritikus esetekben ez ugyanis adatvesztést okozhatna (például a szinkron átvitelnél egy távfeldolgozó vonalon). Példaként elemezzük az IBM 360/370-es hardverrel használható szoftvermegszakító utasítás, a már említett SVC (SuperVisor Call) használatát a rendszerhívások lebonyolításához. Az SVC utasításnak van egy 8-bites közvetlen (az utasításba beépülő) operandusa, amelyet a hívott funkció kódjának megadására lehet használni. A kódszám maximálisan 256 féle értéket vehet fel. Ez lekorlátozza azoknak a rendszerrutinoknak a számát, amelyeket ezzel a hívási móddal aktivizálhatunk. Bár a fejlett OS/VS rendszereknél ez a szám már kezd kevésnek bizonyulni, a 200 körüli rendszerrutin készlet tulajdonképpen igen bő lehetőségekkel felruházott szolgáltatáshalmaz elérését teszi lehetővé. Meg kell jegyezni, hogy a programozási nyelvek könyvtárai ezt a híváskészletet alkalmas paraméterezéssel, és több hívás kombinálásával erősen ki tudják terjeszteni

(makrók, szubrutinok). Sokszor ezeket a tulajdonképpen nem eredeti rendszerhívásokat is a rendszerrutinok közé sorolják. Az SVC nn hívás kiadása programozott megszakítást okoz, amelynek létrejöttét most pontosan nyomon követjük. Az SVC utasítás hardver mikrokódja olyan, hogy az utasítás operandusában szereplő nn értéket félreteszi a PSW (Program Status Word = programállapotszó) megszakítás okát jelző adatmezejébe, és jelzi a hardvernek, hogy a program megszakítást kér. A 360/370-es hardver a megszakítási igényt az SVC utasítás teljes lezajlása után észleli. A PSW utasításcímet reprezentáló része ekkorra már éppen továbbmutat a program következő végrehajtandó utasítására. Ennek végrehajtása azonban nem kezdődik el, hanem a hardver a PSW tartalmát félreteszi a főtár fix mezejébe, az úgynevezett SVC Old PSW-be (régi SVC megszakítási állapotszóba), és a főtár másik fix mezejéből, az úgynevezett SVC New PSW-ből (Új SVC megszakítási állapotszóból) előveszi az SVC megszakítás-kezelő program indítási állapotát. Ez bekerül a CPU PSW regiszterébe, s ez által a CPU az SVC feldolgozórutin végrehajtását kezdi el. Vegyük észre, hogy a hardver megszakítási mechanizmusának be kellett segítenie a régi programállapot megőrzésébe! Ez a segítség abban állt, hogy a régi PSW állapotvektor SVC elemébe elmentődött a megszakított (SVC-t kiadó) program utolsó állapotjellemzőit mutató PSW tartalom. Ez a segítség azonban elég gyenge lábakon áll, hiszen egy újabb SVC megszakítás azonnal letörölné az előzőleg kimentett PSW-t. Az SVC megszakító rutinnak ezért az Old PSW-t azonnal tovább kell mentenie a megszakított program folyamatvezérlő blokkjának állapotvektorába. Az SVC-vel ráadásul még szerencsénk van, mert amíg mi a programból nem adunk ki egy újabb SVC hívást, addig SVC megszakítás nem következhet be. Letiltásával ezért nem kell foglalkozni. Az nem kötelező, hogy az SVC FLIH rutinjából ne adjunk ki Újabb SVC hívást, de nyilvánvalóan csak azután szabad, ha az állapotvektort már elmentettük. Más, például B/K megszakítás-kezelő rutin esetén le kell tiltani a megfelelő megszakításokat. Az IBM 360/370-ben például B/K csatornánként adhatunk ki megszakítástiltást az új PSW megfelelő bitjeinek beállításával. Ez is egy hardversegítség, mert a megszakítás-kezelőben már nem kell a megszakítás letiltásával foglalkozni. Az SVC FLIH az állapotvektor mentése után hozzákezd a hívás kielemzéséhez. A megszakított program PSW-jének megszakítási ok mezejéből előveszi az SVC hívás nn operandusát, és egy ugrótábla segítségével a hívott funkció feldolgozórutinjára adja a vezérlést. Ez a második szintű feldolgozó, amelynek már nem kell feltétlenül tárrezidensnek lennie, és ütemezhető folyamatként is futhat. Amikor az FLIH véget ér, a vezérlést a diszpécser kapja meg, ami a megszakítási esemény hatására beálló környezetet kielemzi, és ez alapján elindítja a következő jogosult folyamat programját. Ehhez előveszi annak állapotvektorát, betölti a megfelelő CPU regiszterekbe, majd utolsó teendőként az elmentett PSW állapotot a CPU PSW regiszterébe töltve "kiprovokálja" a program folytatását. (Ha még emlékszünk rá, az utoljára mentett PSW címszámláló mezeje már éppen a következő végrehajtandó utasításra mutatott.) Általában elmondható, hogy az FLIH legfontosabb feladata a megszakítás előtti állapot megőrzése egy védett adatszerkezetben. Ezután gondoskodik az előállt helyzet kielemzéséről, és, ha lehet, a kért szolgáltatás teljesítéséről (primitív művelet esetén), vagy megszervezi annak teljesítését (folyamatként futó rutin esetén), végül "felébreszti" a diszpécsert. A második szintű feldolgozó rutinok természetesen funkciófüggőek, úgyhogy itt nem foglalkozunk velük részletesebben.

6.3. Alacsony szintű ütemezés Az alacsony szintű ütemező, avagy diszpécser alapfeladata az, hogy kijelölje azt a folyamatot,

amely a CPU-t következőként használhatja, és biztosítsa annak folytatási feltételeit. A CPU-idő szétosztásához nem feltétlenül van szükség ütemezőprogramra. Előre ismert számú program esetén például az időosztásos szimultán üzemet magukkal a programokkal is megszerveztethetjük. Ehhez azonban a programoknak tudniuk kell egymás munkájáról. Ebből indul ki az úgynevezett Round-Robin (RR), magyarul körben forgó ütemezés, amelyet a 6.2. ábra mutat be három program esetére. Az ábrán látható példában az ütemezés lebonyolítása a következő extra igényeket támasztja az egyenkénti futáshoz képest: * Munkaterületek az összes programban az állapotvektor tárolására. * Vezérlésátadó rutin szintén minden egyes programban, amely az állapotvektor mentését és a vezérlés továbbadását végzi. * A futóképesség vizsgálatára szolgáló kód. * Helyreállító kód, amely a megszakítás előtti programállapot visszaállítását, és a program továbbindítását oldja meg. * Egy kapcsolólista és két külső változó. +---------------+ +---------------+ +---------------+ | PGM1 | | PGM2 | | PGM3 | +---------------+ +---------------+ +---------------+ | Munkaterület | | Munkaterület | | Munkaterület | |---------------| |---------------| |---------------| *===>| Futhatok? ===>| Futhatok? ===>| Futhatok? ===>* |---------------| |---------------| |---------------| | Helyreállítás | | Helyreállítás | | Helyreállítás | |---------------| |---------------| |---------------| | PGM1 kód | | PGM2 kód | | PGM3 kód | |---------------| |---------------| |---------------| | Vezérlésátadás| | Vezérlésátadás| | Vezérlésátadás| +---------------+ +---------------+ +---------------+

IX

+---------+ | 1 | +---------+ Indexregiszter

+---------+ MAX | 3 | +---------+ A kapcsolólista hossza

0. 1. 2. 3.

*===============* | Kapcsolólista | +---------------+ | PGM1 címe | +---------------+ =>| PGM2 címe | +---------------+ | PGM3 címe | +---------------+ | 0 | *===============*

6.2. ábra. Round-Robin (körben forgó) ütemezés három programmal A kapcsolólistát, az IX és MAX változókat minden programból el kell tudni érni. Az algoritmus úgy működik, hogy induláskor az IX értéke nulla, azaz, az 1-es programra mutat. Az 1-es program először megvizsgálja, hogy éppen futóképes állapotban van-e. Ha nem, akkor azonnal továbbadja a vezérlést olymódon, hogy az IX értékét 1-gyel megnöveli, és ezzel automatikusan a kapcsolólista

szerinti 2-es programot indítja el. Ha viszont futóképes, akkor a helyreállító rutint indítja, ami a CPU regisztereit -- és ezzel állapotát -- a program előző futásának megszakadásakor érvényes értékekre állítja vissza. Ezután a program algoritmusának egy előírt szakasza zajlik le, majd aktivizálódik a vezérlésátadó kód. Ez az állapotvektor munkaterületre való mentése után ilyenkor is megnöveli az IX értékét 1-gyel, és ezzel indítja a kapcsolólista IX-edik indexű elemében szereplő programot. Ha az IX elérné a MAX-ban található értéket, akkor az IX-et nullázzuk, mielőtt a következő rutinra kapcsolunk. Így belátható, hogy a három program a vezérlést egymás között körben forogva cserélgeti. Ez elég ügyetlen és gazdaságtalan ütemezési rendszernek tűnik, de mellette szól, hogy működőképes. Gazdaságosabb megoldást jelent azonban, ha a szimultán vezérlés funkcióit és adatszerkezeteit erre specializált, külön programba integráljuk. Túlnyomó többségben ezt a módszert használják. A közös diszpécserben csak egyszer kell szerepelnie a vezérlésátadó, a helyreállító, valamint a futás feltételét vizsgáló kódoknak. Így sem kerülhető el a kapcsolótábla, a két vezérlőváltozó és a programonkénti állapotvektor mentésére szolgáló munkaterületek használata. A programoknak azonban ilyenkor egyáltalán nem kell tudniuk egymásról, ami programozási szempontból előnyös lehet. Az ütemező adatstruktúrái elrejthetők a rutint tartalmazó rétegbe, és ezzel védhető a véletlen meghibásodástól. A diszpécser működéséhez tehát speciális adatstruktúrákra van szükség. Ezek közül a legfontosabb az, amely a folyamatok pillanatnyi állapotát őrzi. Ezt mi folyamatvezérlő blokknak nevezzük, de az egyes operációs rendszerekben meglehetősen különböző elnevezéseket adnak neki (aktivációs rekord, inkarnációs rekord, diszpécservezérlő blokk, taszkvezérlő blokk). Erről már több helyen is volt szó könyvünkben, itt viszont láthatjuk ennek az adatstruktúrának a közvetlen szerepét a diszpécser működésében. A folyamatvezérlő blokkokat a diszpécser táblázatként kezeli. E táblázatban minden rekord egy folyamat adatait írja le. Az ütemezés szempontjából egyformán kezelendő folyamatvezérlő blokkokat a diszpécser vagy különböző táblázatokban tartja, vagy ugyanazon a táblázaton belül összeláncolja. Emiatt a folyamatvezérlő blokkokban nemcsak egy folyamat állapotadatai, hanem a diszpécserláncok mutatómezői is benne vannak. Így a folyamatvezérlő blokkok tipikus tartalma: * név vagy más programazonosító (például folyamatsorszám); * tárolóterület (cím, hossz); * B/K hozzárendelések mutatói; * üzemállapot (státusz, futóképesség); * prioritás; * mutatók a létrehozott gyermekfolyamatok folyamatvezérlő blokkjaira, * mutatók az ütemezés szempontjából összetartozó folyamatok vezérlőblokkjainak összeláncolására stb. A tartalomból kitűnik, hogy a táblázatban más táblázatokra mutató adatok is találhatók (B/K hozzárendelések). Ténylegesen a rendszermagot vezérlő adatstruktúrák sokszorosan összeláncolt táblázatokból, listákból, sorokból állnak. Minden folyamatként kezelendő programhoz folyamatvezérlő blokknak kell tartoznia, akár felhasználói programról, akár folyamatként futó rendszerrutinról van szó. Ezért a folyamatra újabb definíciót is adhatunk: diszpécserrel ütemezhető programegység.

A lehetséges folyamatállapotokat ismét kielemezzük a diszpécser szemszögéből nézve. Eszerint a folyamotok állapota lehet: * futó, amikor a diszpécser átadta a programnak a CPU vezérlés jogát; * aktivizálható, amikor a program futóképes, de nincs nála a CPU vezérlés joga; * blokkolt, alvó, amikor azért vették el a programtól a CPU vezérlési jogát, mert éppen nem tudna továbbhaladni, vár egy esemény bekövetkezésére (például B/K átvitel végére); * (a tárból) kiszorított, amikor a diszpécser elvette a programtól a CPU vezérlés jogát, a tárkezelő pedig elvette a korábban neki adott tárterületet, és kimásolta háttértárra (swapping); * feltartóztatott, felfüggesztett, futáson kívüli, amikor a program ugyan futóképes volna, de mégsem adja meg neki a diszpécser a vezérlési jogot, mert valamilyen okból nem teheti (például operátori beavatkozással felfüggesztették a futását); * holtponti, amikor a program olyan esemény bekövetkezésére vár, amely már sohasem következhet be; * befejezett, amikor a program algoritmusa véget ért, és az operációs rendszernek el kell végeznie a folyamat megszüntetésének teendőit. A diszpécserek kifinomult működése még az itt vázoltnál is részletesebb "állapotsereget" igényelhet. Ezért ez a diszpécserek politikájának kialakításában döntő fontosságú kérdés. Ütemezéskor a diszpécser mindig csak a futóképes állapotú programok közül választhat. A programok állapotát a politika eredményeként részben az ütemező befolyásolja, de az ütemező nem tudja a folyamatokat futóképes állapotba átvinni. Ezt a feladatot a megszakítás-kezelők látják el, ezért a diszpécser a megszakítás-kezelőkkel közösen használja a vezérlőtáblázatokat. Ennek kapcsán érdemes kielemezni a blokkolt állapotok konkrét okait, amelyek a következők lehetnek: * várakozás a B/K befejeződésére; * várakozás egy zár felszabadítására; * várakozás más folyamat kimenő adataira; * lapozás (virtuális tár esetén), amikor a kívánt programrész vagy adatmező nincs benn a valós tárban; * a swapping visszatöltési folyamata zajlik stb. A megszakítás-kezelők másodszintű funkciói tudják kielemezni a vezérlőtáblázatok láncait követve, hogy melyik folyamattal kapcsolatos az éppen kezelt megszakítási esemény (például melyik folyamat B/K átvitele zajlott le). Az adott folyamat állapotát az esemény típusának megfelelően meg kell változtatni, így jelezni lehet a diszpécsernek, hogy a kérdéses folyamat már nem blokkolt, hanem futóképes. A diszpécser működését aktivizálhatja, hogy: * (1) az éppen futó program önként lemond a CPU vezérlés jogáról (a WAIT, SLEEP

rendszerhívások valamelyikével); * (2) olyan esemény következik be, ami miatt a legmagasabb prioritású folyamatot kell folytatni; * (3) az időzítő mechanizmus közbelép (lejárt a kijelölt időszelet); * (4) az operációs rendszer elveszi a folyamattól a CPU--vezérlési jogot (adott ütemezési politika döntése folytán). A fenti sorrend bizonyos történetiséget takar, amennyiben elmondható, hogy legkorábban alakult ki a prioritásvezérelt, később az időosztásos és csak legutoljára a komplex ütemezési politika. Ha a diszpécser csak az (1) feltételt veszi figyelembe, akkor politikamentes. Ha az (1) és (2) feltételre együttesen figyel, akkor a diszpécser politikája a nagy prioritású folyamatoknak kedvez, úgymond prioritásvezérelt. Az (1) és (3) feltételeket figyelembe vevő diszpécser nem kivételez a felügyelt folyamatok egyikével sem, hagyja, hogy azok egyenletesen haladjanak, de útját állja a folyamatok önkényeskedésének. A megvalósítási mód miatt ezt a politikát időosztásosnak nevezik. A további kombinációk igen bonyolult politikák megvalósítását teszik lehetővé. Ezeknek számba kell venniük azt, hogy a számítógépes rendszert az operációs rendszer alacsony és magas terhelésénél is hatékonyan lehessen üzemeltetni. Ez a működésoptimalizált politika (például IBM SRM, l. 13. fejezetet). A működésoptimalizáláshoz adatokat kell gyűjteni, ezért a vezérlőtáblázatok bonyolult politikájú diszpécserek esetén, a fentieken túl, további elemekkel bővülnek. Az operációs rendszerben nemcsak egy alacsony szintű ütemező létezhet. Ennek oka az alrendszerek alkalmazásában keresendő (vö. 5.7.-el). Az alrendszeri szolgáltatások folyamatait külön is ütemezni kell. Ezekbe beépíthető az alrendszer szempontjából kívánatos ütemezési politika, amivel tehát nem kell a legalacsonyabb szintű ütemezőt terhelni. Az alrendszeri diszpécserek persze helyzetüknél fogva csak rosszabb hatékonysággal működtethetők. Ez a probléma a tipikus alkalmazásokat figyelembe véve nem kritikus, mert a felhasználók interaktív alkalmazók, akik lassú, emberi reakcióidőkkel dolgoznak, és nem kívánnak túl gyors válaszadást. Más a helyzet a virtuális gépes rendszerekkel, ahol komplett operációs rendszerek, bonyolult politikájú diszpécserekkel működnek a virtuális gépet kezelő operációs rendszer alrendszereiként (l. 14. fejezet). Ilyenkor a hatásfokromlás meglehetősen nyomasztó lehet. Megjegyezzük, hogy a működésoptimalizálás szükségessé teszi egy harmadik, közbenső szintű ütemező alkalmazását is. Ennek okait külön fejezetben tárgyaljuk (l. 13. fejezet). A közbenső szintű ütemező figyeli a folyamatok haladását, és mért statisztikai adatok alapján beavatkozik a diszpécser várakozó soraiba. Megnövelheti például a lassan haladók prioritását, de szükség esetén az erőszakoskodókat időlegesen le is blokkolhatja (l. előbb a folyamatállapotok fajtáit). Konkrét diszpécser algoritmusokról a 9. fejezetben lesz szó.

6.4. Tárkezelési funkciók Erre a témakörre egy külön fejezetet is szántunk (10. fejezet). Itt elsősorban arra szeretnénk rámutatni, hogy a tárkezelés feltétlenül a rendszermag részének kell lennie, és meglehetősen alacsony szintű rétegben kell elhelyezkednie. Ezt persze zavarja -- mint azt már a T.H.E. architektúra kapcsán is elemeztük, -- hogy a virtuális tár kezelése perifériakezelést is igényel. Ha a szigorú rétegezési elveket akarjuk tartani, akkor a tárkezelőben redundáns módon perifériakezelő rutinokat is szerepeltetni kell. Ha pedig lemondunk a szigorú hierarchiáról, akkor a magasabb

rétegben elhelyezkedő perifériakezelőt kell aktivizálni az alacsonyabb rétegben elhelyezkedő tárkezelőből. Ha a két funkciót egyazon rétegben, párhuzamosan valósítjuk meg, akkor közös vezérlőtáblázatokat használhatnak. Ez a helyzet például a UNIX-ban. A korai, nem rétegelt struktúrájú operációs rendszerekben a táblázatok bonyolult összeláncolásával próbálták elkerülni a problémákat, de nem túl sok sikerrel. Ezekben az operációs rendszerekben ma is hemzsegnek a hibák. Az IBM 360/370-re írt operációs rendszerek mindegyikére vonatkozhat ez a megjegyzés. Úgy tűnik, túlhajtották a kódredundancia elkerülésére irányuló erőfeszítéseket. Nem lehet a problémát ilyen egysíkúan kezelni. A CPU után a tár a hardver legfontosabb erőforrása. Sok számítógépes feladat már e két erőforrás birtokában megoldható. A tárkezelést tehát minden operációs rendszer kiemelten kezeli. A tárkezelés alapvetően két szempontból osztályozható: * lapozott vagy nem lapozott, és * valós vagy virtuális. A tárfoglalás lehet: * statikus (fix partíciókkal) vagy * dinamikus (GETMAIN, FREEMAIN funkciókkal támogatva). Ebben a fejezetben csak a dinamikus tárfoglalással foglalkozunk részletesebben, hogy megmutathassuk a lebonyolításhoz szükséges architekturális elemeket. A téma további kifejtése a már említett 10. fejezetben található. A dinamikus tárkezelés sarokpontjai: * a szabad mezők nyilvántartásának módja; * a lefoglalás stratégiája; * a felszabadítás módszere. A problémák elsősorban a valós tárkezelésnél csúcsosodnak ki, hiszen (az igazi!) virtuális tárkezelés esetében -- a fixpartíciós statikus tárkezeléshez hasonlóan -- minden program a saját címmezejében gazdálkodik a tárral. A valós, dinamikus tárkezelés két fő funkciójáról, a GETMAIN és FREEMAIN rendszerrutinokról már korábban is esett szó. Ezek feltétlenül a rendszermag rezidens részében helyezendők el, hiszen a tárfoglalás és felszabadítás igen gyakori tevékenység, különösen dinamikus esetben. A tárkezelés kezeléséhez szükséges adatstruktúra a tártartalom--táblázat. Ez láncolt listák formájában tárolja az egyes folyamatok tárlekötéseit, de használnak másféle adatstruktúrákat is. Az egyik megoldás szerint a láncolt lista elemei a lefoglalt tármezők elején foglalnak helyet. A tárfoglalás szempontjából fontos az úgynevezett szabadmező lánc. Ilyet használnak például az IBM OS/MVT-ben.

A szabad mezők elején mezőleírók vannak, amelyek tipikus tartalma: * mutató a következő szabad mező elejére; * mutató az előző szabad mező elejére; * mezőhossz és státusz. A mutatók lánca a rendszermagban kezdődik, illetve végződik. A végpontokat 0 értékű mutató jelzi (nullpointer). A gyorsabb kereséshez előre és hátramutató lánc is van. Ilyen adatszerkezetet használnak például az IBM OS/MVT-ben. A viszonyokat a 6.3. ábrán tanulmányozhatjuk. A GETMAIN tárfoglaló funkció ilyen adatstruktúra alkalmazása esetében úgy működhet, hogy a szabadmező láncokon haladva keres egy alkalmas méretű tármezőt, és elveszi belőle a kért hosszúságú részt. Ellentmondó igényeket támaszt, hogy melyik szóba jöhető mezőből vegyük el a kívánt részt. Ha azt a politikát követjük, hogy mindig a legnagyobból vágunk le egy darabot, akkor egy idő után rengeteg sok apró, kihasználhatatlan mező keletkezik. A legkevésbé eltérő méretű mező kiszemelése jobb algoritmusnak tűnik, de ezekből meg éppen hogy csak igen apró, végképp kihasználhatatlan mezők maradnak szabadon. Nehéz tehát igazságot tenni. Ha a GETMAIN-nel kiszemeltük az "áldozatot", akkor kettévágjuk. Az eredeti szabadlánc-mutatót át kell alakítani úgy, hogy az foglaltsági státuszt kapjon, és beláncolódjon az igénylő taszk táblázataiba. A maradék tárrészt az elején elhelyezett új listaelemmel be kell kapcsolni a szabad láncba. A FREEMAIN funkció algoritmusa sem magától értetődően egyszerű. Ha egy mező felszabadul, azt nem illik csak úgy "bután" beláncolni a szabad láncba. Ez ugyanis növelné az elaprózódás veszélyét. Ilyen algoritmus esetén két szabad mező kerülhetne közvetlenül egymás mellé. Ezeket nyilván célszerű egyesíteni.

6.5. Perifériakezelés 6.5.1. B/K vezérlőprogram A perifériakezelést a rendszermagok meglehetősen jól elkülöníthető része valósítja meg. Ezt a részt olykor külön név alatt emlegetik. Mi erre a funkcióhalmazra a B/K vezérlőprogram elnevezést fogjuk használni. Az IBM 360/370-es operációs rendszerekben ezt a szerepet töltik be az I/O Supervisorok. A B/K--vezérlő aktivizálódik: * B/K funkcióhívás esetében (akár alkalmazói, akár rendszerfolyamatból, akár más rendszerhívásból ered); * B/K--megszakítások lekezelése után, látszólag a csatornák és perifériák kérelmére. A periféria-lekötés általában nem a B/K vezérlőrendszer része. Ezt az allokátorok, az általános erőforrás--kezelő rutinok végzik a magasabb operációs rendszeri rétegekben. Az allokálás lebonyolításához persze szükség lehet B/K vezérlőprogram--szolgáltatásokra.

G

F

+------------------------------+ | REZIDENS TERÜLET | +----+----+----+ | | >0 | 0 | előremutató elem < visszamutató elem S/H státus/hossz SV Supervisorba

mutat | (szabad mező) | +----+----+----+ | E | >0 | 0 | 0 | E | D | B | F | >0 | | +----+----+ | 2. | >C | >0 | Taszk táblázatok | +----+----+ | 1. | >A | >0 | | +----+----+ | | SUPERVISOR | +------------------------------+

A,B,...G régiócímek 0 láncvégjel Jelenlegi szabadmező lánc: SV > B > E > 0 Jelenlegi szabadmező lánc: 0 < SV < B < E

6.3. ábra. Szabadlánc-struktúra az IBM OS/MVT-ben. 6.5.2. A B/K--szolgáltatások hívása Egy B/K művelet indításához minimum a következő adatokra van szükség: * a berendezés hardvercíme (hardverkódszáma), * a végrehajtandó funkció, * az átviendő adatok címe. Ezek az adatok azonban csak rögzített blokkméretek (például lyukkártya, sornyomtató), és egyetlen átviteli csatorna létezésekor elegendőek. Ha ezek nem teljesülnek, akkor további adatokra is szükség van: * a hardverstruktúra bonyolultsága, * a törekvés a berendezés-független adatkezelésre, * a berendezések osztott használatának felmerülése (mágneslemezek). A szükséges további adatok az alábbiak lehetnek: * csatornacím, * transzporthossz, * a B/K-kérések és a kérelmezők összeláncolása, * a berendezés--állomány összefüggések adatai, * az adatállomány--program összefüggés stb. A szükséges adatokat itt is bonyolult, összeláncolt táblázatok képezik, melyek össze vannak láncolva a már említett diszpécservezérlési táblázatokkal is. A cél, hogy a perifériákat minél rugalmasabban lehessen kezelni (kisteljesítményű számítógépes alkalmazásokat kivéve). Az állománytípus és a berendezés-hozzárendelés megadható: * a programok forrásnyelvű szövegében (ez később már nem módosítható, tehát csak statikus kezelést tesz lehetővé); * a munkavezérlő, vagy a parancsnyelvekben (ez dinamikus kezelést biztosít) * a rendszerkatalógusokban, amelyet alapértelmezések megadására használnak. 6.5.3. IBM 360/370 OS/MVT vezérlőtáblázatok Példaként nézzük meg, hogy milyen táblázatokat használ az IBM OS a perifériaműveletek kézben tartására. Kiindulásul megvizsgáljuk, hogy mi történik a DD JCL utasítás feldolgozása során.

A DD utasítás fő (kulcsszavas!) paraméterei: DSN=

adatállománynév (Data Set Name);

UNIT=

a fizikai berendezés azonosítója;

VOL=SER=

a fizikai hordozó azonosítója (kötetsorszám);

DISP=

az adatállomány állapota, kezelésmódja;

LABEL

a címkeinformációk típusa;

DCB

a logikai állapotjellemzők, részletesebben: . állománytípus (adatelérési módszer!), . blokkméret/logikai rekordhossz, . logikai rekordtípus, . kulcsjellemzők, ha vannak, . pufferelési jellemzők stb.

A beolvasó program, és a főütemező a DD utasítások adataiból a 6.4. ábrán látható táblázatsereget generálja. A táblázatok generálása persze a JOB utasításból generálódó munkavezérlő blokk (angolul: JCB = Job Control Block) létrehozásával kezdődik. Ehhez láncolódnak a munkához tartozó DD utasításokból képződő táblázatok. A JCB-hez kapcsolódó első, a munka állományigényeit összegyűjtő, táblázat a munkaállomány-vezérlő blokk (angolul: JFCB = Job File Control Block). Amikor a vezérlőáram--olvasó (beolvasó) talál egy DD utasítást, akkor annak adataiból létesít egy JFCB blokkot. Ugyancsak keletkezik egy másik vezérlő blokk is az úgynevezett lépés B/K táblázatban (angolul: SIOT = Step I/O Table), amely nyilvántartja azt, hogy melyik EXEC utasításhoz -- azaz munkalépéshez, -- kapcsolódik a feldolgozott DD utasítás. A munkához tartozó táblázatok akkor épülnek tovább, amikor a főütemező beütemezi végrehajtásra a munkát. Az első munkalépés programjának indítását végző Iniciátor program létesít egy folyamatvezérlő blokkot (ezt IBM terminológiával taszkvezérlő blokknak hívják: TCB = Task Control Block). A program futásához szükséges erőforrásokat az Iniciátor a JFCB és SIOT táblázatok alapján igyekszik lefoglalni (most eltekintünk az esetleges lefoglalási problémáktól). A SIOT alapján az Iniciátor létesít egy ehhez hasonló tartalmú táblázatot, amely már a programból képzett folyamathoz, IBM terminológiával taszkhoz tartozik (TIOT = Task I/O Table = taszk B/K táblázat). Miért van szükség erre a másolatra? Ez a gyermekfolyamatok (IBM terminológiával altaszkok) létrehozásával kapcsolatosan merült fel. Az altaszkoknak ugyanis külön TIOT-ra van szükségük a független működéshez. Így ha egy munkalépés indítótaszkja további altaszkokat szül, akkor azok mindegyikéhez keletkezik egy TIOT, de a munkalépéshez továbbra is csak egy SIOT táblázat tartozik. A JFCB, SIOT, TIOT vezélőstruktúrákkal tartja kézben az OS a MunkaMunkalépés-Taszk feladathierarchiát. (A 6.4. ábra csak egy taszkhoz tartozó táblázatokat mutat.)

A TIOT hozzá van láncolva a taszk TCB blokkjához. A TIOT tételeinek tartalma: * a JOB neve, * a lépés neve, * mutató egy JFCB tételre, amely a vonatkozó DD utasítás adatait tárolja, * mutató az allokált periféria UCB tételére. +----------+ ---> | | ----> | | EXEC ---> | Beolvasó | | | DD ---> | | ----> +----------+ JOB

O=====O | JCB | O==v==O | O==v===O O======O | JFCB | ---> | SIOT | Ov====vO O=v====O | | | +---------------+ ++---------++ | | Iniciátor/| | | Terminátor| | +-v---v---v-+ | +---+ | +---+ +----v----+ | | | | | O====v=O | O=v====O | Open/ | IOB | | | | B/K | O==v==O +---------+ Ov===vO | | |megszakítás| | | | | | | | |feldolgozó,| +-------> | Put/Get | --+ | | | +------v----+ +---------+ | Ov==v=vO | +---> RB | rendszerlistázó > munkafelügyelő. Ezzel figyelembe vettük a perifériakezelési sajátosságokat. A rendszerolvasó perifériájáról feltételezhetjük, hogy az a leglassúbb, ezért ritkán fog kiszolgálást kérni. Ha azonban kér, akkor célszerű szinte azonnal kiszolgálni, mert utána úgyis megint elég hosszú ideig békén hagy bennünket. Ezért kell neki adni a legnagyobb prioritást. Ugyanakkor a munkafelügyelő erősen CPU-igényes. Ha nem akarjuk, hogy túlzottan kisajátítsa a CPU-t, akkor neki kell adni a legkisebb prioritást. Feltételezzük, hogy a vezérlés mindig visszatér a munkavezérlőbe, amikor egy munkalépés lezajlik. A munkákról tételezzük fel, hogy olyan kártyakötegekből állnak, amelyeket egy munkaazonosító vezérlőkártya vezet be, ezt forrásprogram kártyák követik a program végét jelző vezérlőkártyával, majd a futáshoz szükséges adatok következnek az adatok végét jelző vezérlőkártyával, és az egészet egy munkazáró vezérlőkártya zárja le (ez utóbbi már redundánsadat, de megkövetelése leegyszerűsítheti a vezérlő algoritmusát). Spooling rendszerünknek tehát három adatfajtát kell kézben tartania: programszövegeket, bemenő adatokat, és eredményadatokat. Ezeket tegyük fel, hogy három könyvtárban mágneslemezen tároljuk. A lebonyolítást egy B/K vezérlőrendszerre bízzuk, amely megoldja a mágneslemez szabadhely-gazdálkodását, valamint a felvett állományok nyilvántartását és elérését. A munkákról feltételezzük, hogy a következő lépéseken mennek át: * (1) Beolvasás:

a munkák adatai lemezre kerülnek;

* (2) Várakozás:

a munka végrehajtásra kész;

* (3) Futás:

a munka végrehajtódik;

* (4) Befejeződött:

a munka eredménye nyomtatásra várakozik;

* (5) Kiírás:

a munka eredménye kinyomtatódik;

* (6) Vége:

a munka elkészült.

A következő tartalmú vezérlőrekord szükséges egy munka adatainak nyilvántartásához: * munkaazonosító * állapot

* mutató a programállományra * mutató a bemenő adatokra * mutató a kimenő adatokra A munkasor ilyen tartalmú rekordok láncolt listájaként alkotható meg. Ez a sor egy példa az osztott erőforrásokra, mert mindhárom rendszermodul használja a működéséhez. Ilyenkor biztosítani kell az adatok integritását, ami azt jelenti, hogy amíg az egyik program ír valamelyik rekordba, addig azt más program ne olvassa, mert félrevezető információt kaphat. A rendszerolvasó egy új munka beolvasásakor készít a munkasorban egy új tételt. Ez a tétel addig nem törlődik a listából, amíg a munka el nem éri a "Vége" állapotot. Váratlan rendszerleállásnál a rendszer felélesztése után ez teszi lehetővé a munka újraindítását. Az indulási állapot persze a "Beolvasás". Ebből a munkafelügyelő modul tudhatja, hogy még nem kezdheti el a program végrehajtását, hiszen azt előbb be kell olvasni. Munkafelügyelő programunkban a fordítóprogram és a lefordított program aktivizálását szubrutinhívásként képzeljük. A B/K lebonyolításával kapcsolatos feltételezést már említettük. Az egész modell elhanyagolja a konkurens műveletek szinkronizálásának problémáját, amelyet egy pontosabb modellben meg kell oldani. Felügyelőprogramunk ily módon kiegészítendő a munkafelügyelő programon kívül a szinkronizáló rutinok, a megszakítás-kezelők, és a B/K kezelő rutinjaival stb. Ezek működtetése további táblázatok létrehozását és kezelését fogja igényelni. A példa további boncolgatását a tanultak alapján az olvasóra bízzuk. Megjegyezzük még, hogy a három programmodul párhuzamosságát sem jelöltük. Erre vonatkozóan a 12. fejezetre utalunk. Spooling rendszerünk vázlatos programterve mindezek után a következő lehet: Rendszerolvasó: ISMÉTELD munkaazonosító kártya olvasása munkasor tétel készítése "Beolvasás" állapot beállítása programbeolvasás és elhelyezés lemezen üres állomány létesítése az eredményeknek "Várakozás" állapot beállítása VÉGTELENSZER Rendszerlistázó:ISMÉTELD "Befejeződött" állapotú munka keresése eredménylistázás állományok törlése munkasor tétel törlése VÉGTELENSZER Munkafelügyelő: ISMÉTELD "Várakozás" állapotú munka keresése programfordítás HA hibátlan AKKOR programfutás "Befejeződött" állapot beállítása VÉGTELENSZER

6.8. Gyakorlatok 6.8.1.

Mi a rendszermag és mi a szerepe?

6.8.2.

Mit nevezünk rezidens és mit tranziens rutinnak?

6.8.3.

Mi a primitív művelet és mi az ellentéte?

6.8.4.

Miért tárrezidens a legtöbb magfunkció?

6.8.5.

A magfunkciók jó része megszakíthatatlan rutinként fut. Miért van erre szükség?

6.8.6.

Miért kell az operációs rendszeri funkciók rutinjainak a hardver valamelyik privilegizált üzemmódjában futnia?

6.8.7.

Milyen a helyes rendszermag-struktúra? Miért?

6.8.8.

Milyen célt szolgálnak a vezérlőtáblázatok?

6.8.9.

Mire szolgálnak a zármechanizmusok, és mi a működési elvük?

6.8.10.

Mi a "kritikus szakasz"?

6.8.11.

Mi a diszpécser, és hogyan működik?

6.8.12.

Mi váltja ki a diszpécser működésbe lépését?

6.8.13.

Milyen operációs rendszeri szolgáltatástípusokról volt szó?

6.8.14.

Mi a rendszerhívások szerepe, és hogyan szokták őket megvalósítani?

6.8.15.

Hogyan történik a rendszermagban a megszakítások kezelése?

6.8.16.

Melyek a dinamikus tárkezelés fő rendszerfunkciói?

6.8.17.

Mi a B/K vezérlőprogram?

6.8.18.

Mi az OPEN szerepe, és hatására hogyan reagál a B/K vezérlőprogram?

6.8.19.

Mi történik egy B/K kérelemmel?

6. Hogyan fejeződik be egy B/K igény kielégítése?

OS07V10.rtf,ZSP,2001-04-16

7. RENDSZERHÍVÁSOK

A rendszerhívások azok a programutasítások, amelyekkel programunkból operációs rendszeri szolgáltatásokat tudunk kérni. Erről már több fejezetben is volt szó, de itt összefoglaljuk az ezzel kapcsolatos kérdéseket. Mégegyszer tisztázni kívánjuk a primitívként és a folyamatként futó rendszerhívások közötti különbségeket. Különösen azért, mert az irodalom is eléggé eklektikusan használja a primitív művelet fogalmát: lényegében minden operációs rendszeri, sőt alrendszeri hívást primitívként emlegetnek. Ez elvileg definíció kérdése, de mi inkább azok pártján állunk, akik gyökeresen megkülönböztetik e két rendszerfunkció aktivizálási módot.

7.1. Rendszerprimitívek Az operációs rendszerek (vagy alrendszerek) azon funkcióit, melyeknek algoritmusa homogén (egy célnak szentelt) kód, és igénybevételét nem kell diszpécserrel ütemezni, primitív műveleteknek nevezzük. A primitív funkciók kódja természetesen tartalmazhat elágazásokat, ciklusokat, sőt még szubrutinhívásokat is, de a végrehajtás során nem keletkezhet olyan helyzet, amelyben a rutin végrehajtása megakad. Elakadásnál ugyanis el kellene venni a rutintól a CPUvezérlési jogot, és ez már bejegyzéseket igényelne a rendszertáblázatokban, továbbá a diszpécser beavatkozását tenné szükségessé. A primitív műveletek algoritmusa olyan, hogy helyes működésüket olykor a megszakítások is zavarnák. Bár egyes rutinok megszakítása megengedhető olymódon, hogy a megszakítás elsőszintű lekezelése (FLIH lefutása) után a rutin azonnal visszakapja a vezérlést, a gyakorlatban a primitív műveletek futása alatt letiltják a megszakításokat. Természetesen, mivel egyes megszakításokat időben illik kiszolgálni, a primitív funkciók csak meglehetősen rövid lélegzetű rutinok lehetnek, különben megzavarnák a megszakítások kiszolgálását. Az operációs rendszerek tervezőinek meg kell találni a kompromisszumot a két ellentmondó igény között. Nem megszakítható primitív funkcióként kell például megvalósítani a már említett P és V szemaforkezelő műveleteket. Ugyanakkor a primitívként beprogramozott, tehát nem folyamatként futó, diszpécserrutin általában túl bonyolult művelet ahhoz, hogy teljes végrehajtása alatt le lehessen tiltani a megszakításokat. Kódjában csak kifejezetten azokon a kritikus szakaszokon szabad letiltást használni, ahol a megszakítások a diszpécser működését tényleg zavarnák. Az is természetes azonban, hogy a diszpécser azonnal visszakapja a vezérlést, amint az FLIH rutin végrehajtódik, hiszen éppen ő az ütemező, aki eldönti, hogy melyik folyamat kaphatja meg a CPU vezérlésének jogát. A diszpécser alkalmanként még jól is jár, ha engedi a megszakításokat, mert ezzel menet közben frissebb információkhoz juthat a környezeti eseményekről, és ezáltal ütemezési döntéseit is jobban megalapozhatja. A primitív funkciókat megvalósító rutinok szinte kötelezően tárrezidensek. Ennek az az oka, hogy

ezeknek az algoritmusoknak gyorsan kell reagálniuk, hiszen azért írták meg őket primitívként. Ha nem tartózkodnának állandóan a valós operatív tárban, akkor megakadna működésük, ami a fentebb mondottak értelmében primitívek esetén lehetetlen szituáció. A felmerülő időkésleltetés ráadásul elég nagy lenne, ha tranziens rutinként a háttértárról kellene elővenni a kódot. A háttértárak elérési sebessége a legkorszerűbb mágneslemezes perifériák esetében is 4-5 nagyságrenddel lassúbb, mint az operatív tár elérése (RAM: általában kisebb, mint 1 mikrosec, háttértár: legalább 10-20 millisec!). Az operációs rendszerek tervezőit a fenti meggondolások vezérelhetik annak eldöntésében, hogy egy funkciót primitív vagy folyamatként futó rendszerhívásként valósítanak meg. Elképzelhető, hogy egyes algoritmusokat kényszerűségből két vagy több primitívre kell felszabdalni, és velük kell megszervezni a rendszerhívást kiszolgáló rutint egy magasabb hierarchia szintű rétegben folyamatként futó funkcióként. A primitív funkciók működését a 7.1. ábra szemlélteti. Hívó program

Rendszermag

= (a tárcímek lefelé nőnek) = | 2 | + x-------------------->>+ p PROGRAM(p) | 3 # FLIH(#) p |2 # 1 v 2 | v 4 CALL >>--------------------/ SCALL >>--x .. |4 v 11 | | 8 # 9 | 12 p |11 | *>>-|------x p ? 7| | 5 | 9| p | +--x .. |5 v 11 | | 8 # 9 | 12 p |11 | *>>-|------x p ? 7 | | 5 | 9| p | +