Tartalmi kivonat
NetAcademia-tudástár Ki tartja a kezében a szálakat? Remélhet leg az Olvasó is rájött már, hogy nem az aktuális bel-, vagy akár világpolitikai színpad mögé fogunk bepillantani a következ néhány oldalon (ha jól csinálják, oda úgysem lehet). Természetesen az operációs rendszer által futtatott folyamatok (processzek) végrehajtási szálairól (thread-ek), azok id zítésér l, futtatásáról lesz szó, egészen pontosan arról, hogy mikor ki „fut”, ki birtokolja a processzor(oka)t – az is kiderül majd, hogy a címben feltett kérdésre a Windowsvilágban nincsen konkrét válasz. Ez a dokumentum a NetAcademia Kft. tulajdona Változtatás nélkül szabadon terjeszthet 2000-2003, NetAcademia Kft 1 NetAcademia-tudástár Cikkünk David Solomon [1] Barcelonában, a Tech.Ed 2001-en elhangzott el adása, valamint ugyan és Mark Russinovich Inside Microsoft Windows 2000 (Third Edition) [2] cím könyvének aktuális fejezete alapján készült. Ez a
könyv egyébként ajánlott, s t, kötelez olvasmány mindenkinek, aki szeretne komolyabban foglalkozni a Windows lelkivilágával. Nagyvonalakban A Windows NT/2000 (továbbiakban csak Windows) preemptív, multitaszk operációs rendszer, amelyben a végrehajtási szálak prioritása határozza meg azok végrehajtási sorrendjét, id zítését. A preemptív szó jelentése körülbelül „el jog”, ami bizony azt jelenti, hogy – igencsak nem demokratikus, de mégis m köd módon – ha jön valaki, akinek nagyobb prioritása van, mint az éppen futó végrehajtási szálnak, azt bizony el reengedi a sorban (s t, szerszámait eldobálva félreáll), bármit is csinált éppen. Hogy ne legyen teljes káosz és anarchia, az „elnyomottakat” az operációs rendszer néha különféle mannákkal segíti: hol a szál végrehajtási idejét (kvantum) növeli meg picit (ha egyszer mégis rákerült a sor és futhat), hol a prioritásán emel valamennyit (hogy mégis rákerüljön a
sor és futhasson). Miel tt azonban az id zítés rejtelmeibe belemennénk, tekintsük át a folyamatok és végrehajtási szálak kapcsolatait. Folyamatok és végrehajtási szálak A felhasználó számítógépén alkalmazásokat futtat: ilyen alkalmazás a szövegszerkeszt , a böngész , vagy mondjuk egy könyvel program. Az alkalmazás általában (bár nem mindig) egy folyamat, processz (process) Amikor az alkalmazás elindításáról, leállításáról beszélünk, tulajdonképpen mindig az alkalmazást „képez ” processzt értjük alatta. Ha hinnénk a Task Manager-nek, azt hihetnénk, a gépen egyetlen alkalmazás fut Ha a Task Manager Applications oldalára kattintunk, láthatjuk az éppen futó alkalmazásokat – azazhogy a kép ezt sugallja, holott ez természetesen nem igaz. Egyrészt, itt nem láthatók a rendszert önmagát képez folyamatok, a rendszerszolgáltatások, de még azok az alkalmazások sem, amelyek a TaskBar-on bújnak meg az óra mellett:
miközben a TaskBar-on sorakoznak az ikonok Ezek szerint a személyes t zfalam, a vírusírtóm, az SQL Server Service Manager, vagy az ICQ-m nem fut, esetleg nem is alkalmazás? Dehogynem! Csak a Task Manager nem teljesen mond igazat (ez egyébként általában jellemz rá): az Application oldalon azok az alkalmazások láthatók, amelyek az aktuális felhasználó munkaasztalán nem rejtett ablakokat birtokolnak. Nyissuk ki az ICQ-t! Aktiváljuk a vírusírtót! Rögtön megjelennek a Task Manager-ben is Van más apró hazugság is ezen az oldalon: az alkalmazás neve mellett látható állapotjelentés (Status), ami az esetek többségében „Running” (azaz: fut), illetve „Not Responding” (azaz: nem válaszol). A feliratok azonban a háttérben teljesen mást jelentenek: Running: a folyamat válaszol a Windows üzenetekre (felhasználói beavatkozásra vár); viszont nem fut sehova, Not Responding: a folyamat nem reagál a Windows üzenetekre, így a felhasználói
beavatkozásra sem; de ett l még lehet, hogy teljesen jól érzi magát, s t, fut, csak el van foglalva. Ilyenkor általában valamilyen I/O m velet (lemezes vagy hálózati kommunikáció) befejezésére vár. Szerencsére a Task Manager részletesebb információkkal is szolgál a Processes oldalon. Itt már a számítógépen éppen futó összes processz (folyamat) látható, köztük megtalálhatók az el z oldalon felsorolt alkalmazások, de a többi alkalmazásunk éppúgy, mint a rendszerszolgáltatásokat, s t az operációs rendszer alapszolgáltatásait képez folyamatok is. Ha valaki kíváncsi lenne arra, hogy az Applications oldalon található alkalmazás valójában melyik folyamat, kattintson jobb gombbal az alkalmazás nevére, majd válassza a „Go To Process” parancsot. A Task Manager ekkor a Processes oldalra vált, és kijelöli a kérdéses folyamatot. Processzek és szül k Vegyük kicsit közelebbr l szemügyre, mit árul a Task Manager egy folyamatról:
Ez a dokumentum a NetAcademia Kft. tulajdona Változtatás nélkül szabadon terjeszthet 2000-2003, NetAcademia Kft 2 NetAcademia-tudástár A View menü Select Coloumns parancsával kiválaszthatjuk, milyen információt szeretnénk látni a processzekr l Az alapértelmezésben kiválasztott információk mellett más adatokat is megjeleníthetünk, ha a Task Manager View menüjében a Select Coloumns parancsot választjuk. Az ábrán is látható listából a számunkra most a PID (Process Identifier), a Base Priority, valamint a Thread Count mez érdekes. Kapcsoljuk is be ezeket a mez ket, kés bb még jól jöhetnek (az oszlopok sorrendjét egyébként a Task Manager-ben húzd-és-ejtsd módszerrel át is rendezhetjük). Minden processz rendelkezik egy saját azonosítóval (ez a PID, Process Identifier). Bármilyen m veletet végzünk, a háttérben mindig ennek az azonosítónak a segítségével hivatkozunk az adott folyamatra. Ezen kívül minden folyamat tudja
magáról azt, hogy ki a szül je (ki hozta létre). Ez az információ a Task Manager-ben közvetlenül ugyan nem látszik, de a tudást használja: ha egy folyamat nevére jobb gombbal kattintunk, a megjelen menüben választhatjuk az „End Process Tree” parancsot is, ilyenkor a Task Manager a szül azonosítók segítségével felkutatja a rokoni szálakat, feltérképezi a családfát, és módszeresen végez a famíliával (legalábbis a kiszemelt áldozattal és annak leszármazottjaival). Tiszta maffia Igen ám, csakhogy minden processz csak a saját szül jére emlékszik, a távolabbi rokonokra már nem. Hozzunk létre egy próbakörnyezetet: Nyissunk egy közönséges parancssori ablakot. A parancssorba gépeljük be: start cmd. A parancs hatására egy második parancssori ablak jelenik meg A második parancssori ablakba pedig írjuk ezt: notepad.exe A létrehozott családfát jól jelképezi a Windows 2000 Support Tools-ban (amely minden Windows 2000 CD /support/tools
könyvtárából feltelepíthet ) található tlist /t parancs kimenete: C:>tlist /t . explorer.exe (976) Program Manager CMD.EXE (1768) W:WIN2KPROSystem32cmdexe CMD.EXE (816) W:WIN2KPROsystem32CMDEXE notepad.exe (812) Untitled - Notepad . A parancs eredményéb l csak az aktuális részt vágtuk be: látható, hogy az „ sapa” az explorer.exe A szül -gyermek viszonyokat a behúzások jelzik; ha valakinek nincs se (ilyen az explorer.exe is), az a sor bal szélére kerül Ha az 1768-as PID-j cmd.exe-t és leszármazottjait leállítjuk (Task Manager, Processes oldal, End Process Tree parancs), az magával rántja a másik parancssori ablakot és – természetesen – a NotePad-et is. Ha viszont a köztes parancssori ablakot bezárjuk (a hagyományos módon), a tlist /t kimenete így módosul: C:>tlist /t . explorer.exe (976) Program Manager CMD.EXE (1768) W:WIN2KPROSystem32cmdexe . notepad.exe (812) Untitled - Notepad . A 816-os PID-j cmd.exe már nem fut; a notepadexe
pedig „elanyátlanodott” (egészen a sor elejére csúszott), és pontosan ez menti meg az életét! Ha most végeznénk a cmd.exe-vel és gyermekeivel, a NotePad még vígan m ködne tovább Az ne zavarjon meg senkit, ha esetleg egy gyermek processz PID-je alacsonyabb, mint a szül jéé: a PID-k újrafelhasználhatók, ha valaki elengedi, egy következ létrehozott folyamat felveheti. Ez a dokumentum a NetAcademia Kft. tulajdona Változtatás nélkül szabadon terjeszthet 2000-2003, NetAcademia Kft 3 NetAcademia-tudástár A végrehajtási szálak Minden processz legalább egy végrehajtási szálat tartalmaz, ez a processz úgynevezett „Initial Thread” (kezdeti végrehajtási szál). Az operációs rendszer szempontjából igazán a végrehajtási szálaknak van értelme, az id zítés is végrehajtási szálakat kezel – a processz nem más, mint egy vagy több végrehajtási szál közös adminisztratív környezete. A kezd thread kés bb újabb szálakat hozhat
létre egy-egy részfeladat elvégzésére. Ha a Task Manager-ben megfigyeljük, a „Threads” oszlopban láthatjuk, hogy melyik processz hány végrehajtási szál képében „testesül meg”. A Task Manager „Threads” oszlopában a végrehajtási szálak száma látható Észrevehet , hogy míg a notepad.exe megelégszik egyetlen végrehajtási szállal, a navapsvcexe (egy vírusírtó rendszerszolgáltatása) már nyolc szálat futtat. De próbáljunk csak a jegyzettömbben megnyitni valamit! A végrehajtási szálak száma azonnal megn (a dialógusablak kezeléséhez a rendszer további szálakat hozott létre). Process Viewer A fenti ábrán egy másik nagyon hasznos eszköz látható. Ez a Process Viewer (pviewerexe), ami ugyancsak a Windows 2000 Support Tools része. A Process Viewer jóval részletesebb információkkal szolgál, mint a Task Manager, láthatjuk például, hogy az egyes folyamatok, végrehajtási szálak milyen prioritással rendelkeznek, illetve azt,
hogy az egyes végrehajtási szálak mennyi processzorid t használtak fel felhasználói és privilegizált (rendszer) futási módban. Ha akarjuk, a „Kill Process” gomb segítségével leállíthatjuk a kiválasztott folyamatot, de vigyázzunk, ez az eszköz véres kez , és véresen komolyan veszi a kérésünket még akkor is, ha a szóban forgó áldozat éppen akár egy rendszerszolgáltatás (a Task Manager például az ilyen processzeket jogosultság hiányában nem hagyja leállítani). A végrehajtási szálak futásának id zítése Id zítés tekintetében a processznek, mint fogalomnak nincs jelent sége: a Windows a végrehajtási szálak futását kezeli. Bár a rendszerben látszólag egyszerre akár több száz végrehajtási szál is futhat, valójában egyidej leg csak annyi fut, ahány processzor van a gépben (ha több processzorunk van, alapértelmezésben bármelyik processzoron bármelyik szál futhat, de a végrehajtási szálak kiválaszthatják a nekik
„szimpatikus” processzor(oka)t – ez a Processor Affinity –. Ilyenkor a végrehajtási szál csak a kiválasztott processzoron fog futni, még akkor is, ha a másik éppen üresjáratban van.) Hogy mégis fenntartsuk az egyidej ség látszatát, minden végrehajtási szál csak egy bizonyos ideig futhat, azután át kell adnia a helyét a következ nek. Azt, hogy a sorban ki következhet, a végrehajtási szál pillanatnyi prioritása dönti el Mindenekel tt tekintsük át egy-egy végrehajtási szál életciklusát: Ez a dokumentum a NetAcademia Kft. tulajdona Változtatás nélkül szabadon terjeszthet 2000-2003, NetAcademia Kft 4 NetAcademia-tudástár A végrehajtási szálak életciklusa A végrehajtási szál létrehozásakor inicializált (Initialized) majd futásra kész (Ready) állapotba kerül. A legtöbb szál ebben az állapotban id zik a legtöbbet. Amikor a rendszer a végrehajtási szálat kiválasztja futásra, készenléti (StandBy) állapotba
kerül; innen pedig – hacsak közben nem „érkezett” egy magasabb prioritású szál – futó (Running) állapotba jut. Ebben az állapotban csak egy ideig maradhat, ezt az id t a szál részére fenntartott id szelet érték, a Quantum határozza meg. Ha az id szelet lejárt, a végrehajtási szál újra a futásra kész állapotba lép Ha a végrehajtási szál végleg befejezte a munkáját, leáll: befejezett (Terminated) állapotba kerül. Ezután a végrehajtási szálat vagy megszüntetjük, vagy kés bb újrainicializáljuk (reinkarnáció). A végrehajtási szálak azonban sokszor nem töltik ki a rendelkezésükre álló id szeletet: egyrészt, önszántukból várakozó (Waiting) státuszba léphetnek, amíg egy I/O m velet, vagy kernelfunkció visszatérésére várnak. Másrészt, a Windows saját hatáskörben felfüggesztheti egy végrehajtási szál futását, ha azt észleli, hogy egy fontosabb szál kész a futtatásra. A Windows a következ esetekben dönthet
az éppen futó szál megszakításáról: Új végrehajtási szál futásra kész – mert új szál jött létre, vagy tért vissza várakozó státuszból Az éppen futó végrehajtási szál elhagyja a futó státuszt – mert lejárt a számára kijelölt id szelet; mert várakozó állapotba lépett, vagy mert végleg befejezte a m ködését Valamelyik végrehajtási szál prioritása megváltozik – ha önmaga, vagy akár az operációs rendszer módosítja a szál prioritását Ha a futó végrehajtási szál Processor Affinity értéke megváltozik A fenti esetek mindegyikében a Windows megvizsgálja a futásra kész szálak prioritását, és ha azok közül van, amely magasabb, mint az éppen futó végrehajtási szálé, bizony helycsere következik. Az aktuális állapot elment dik, és a kiválasztott szál állapota tölt dik be a helyére – ezt a m veletet nevezzük kontextusváltásnak (context switching). A végrehajtási szálak aktuális állapotát egyébként
a Performance Monitorban is figyelemmel követhetjük: A fels (vastag vonallal rajzolt) érték a NotePad, a másik kett a Performance Monitor egy-egy végrehajtási szálának állapotértékei Az egyes értékek jelentését az el z ábrából leolvashatjuk. Látható, hogy a NotePad (felhasználói inputra) várakozó és futásra kész állapot között mozog, de futó státuszba – látszólag – soha nem lép. Hogy miért? Azért, mert egyprocesszoros gépen az adatok begy jtésének pillanatában bizony a Performance Monitor adatgy jt végrehajtási szála fut! Ez a dokumentum a NetAcademia Kft. tulajdona Változtatás nélkül szabadon terjeszthet 2000-2003, NetAcademia Kft 5 NetAcademia-tudástár A prioritás A processzorhoz jutás el jogát a végrehajtási szálak prioritása határozza meg. A rendszer „belül” 32 különböz prioritási szintet különböztet meg. A 32 szint két f részre van osztva; az alsó értékek (015) az úgynevezett dinamikus, a
fels rész (16.31) pedig az úgynevezett valósidej prioritási értékek A 0 prioritási érték nem osztható ki, az mindig a Zero Page Thread tulajdona. A prioritási értékek ilyen durva szétválasztására azért van szükség, nehogy magát az operációs rendszert képez végrehajtási szálak is áldozatul essenek a prioritásért vívott harcban. Az operációs rendszer (pontosabban a kernel) végrehajtási szálai tehát eleve sokkal magasabb prioritásértéken futnak, mint a felhasználói szálak. A felhasználói felületre kivezetett prioritásértékek nem számszer ek, hanem szöveges megjelenés ek, úgynevezett prioritásosztályok. Minimális, közép és maximális értékeik a következ k: Idle, Low Below Normal Normal Above Normal High Real-Time üresjárati, alacsony normális alatt normális normális felett magas valósidej min. 2 alap 4 max. 6 4 6 8 11 22 6 8 10 13 24 8 10 12 15 26 Minden szálnak két prioritási jellemz je van: az úgynevezett
alap (base) és a pillanatnyi (current). Valósidej prioritás esetén ez a két érték mindig megegyezik, dinamikus prioritás esetén viszont nem feltétlenül: a Windows a pillanatnyi prioritást az igényeknek megfelel en változtatja. A prioritások értékét többek között a Task Manager, a Process Viewer és a Performance Monitor segítségével tekinthetjük meg (a feladatkezel vel az alap prioritást módosíthatjuk is). 1 2 3 4 A NotePad végrehajtási szála prioritásértékének változása: a vékonyabb vonal az alap (base) a vastagabb a pillanatnyi (current) prioritás A fenti ábrán látható, hogyan változott a NotePad végrehajtási szálának prioritása, miközben várakozott ( ), miközben dolgoztunk vele ( ), illetve amikor alacsony (Low, ) vagy amikor magas (High, ) prioritást állítottunk be neki a Task Manager-ben. Priority Boost A dinamikus prioritás változásai az úgynevezett Priority Boost (prioritás-növelés) következménye. A
végrehajtási szál dinamikus prioritásértékét a Windows a következ esetekben emelheti meg: I/O m velet befejezése után Kerneleseményekre való várakozás után Az el térben futó alkalmazás várakozó állapotból való visszatérésekor A felhasználói felület végrehajtási szálainál felhasználói aktivitás esetén Amikor egy végrehajtási szál már régóta nem futott A megemelt prioritású végrehajtási szálak el jogot kapnak a processzor használatára. A „boost” mindig a végrehajtási szál alapprioritásához adódik hozzá, és hatása id vel el is múlik (a prioritás visszaáll az eredeti értékre). A Quantum A dinamikus m ködés másik biztosítéka a végrehajtási szálak futási id szeletének változtatása (ha egy szál végre hozzáfért a processzorhoz, legalább hadd használja kicsit tovább). Az id szelet hossza egyébként eleve más-más a Professional és a Server operációs rendszereken, de ez a beállítás módosítható. A
Quantum alapértelmezett értéke Professional esetén 6, Ez a dokumentum a NetAcademia Kft. tulajdona Változtatás nélkül szabadon terjeszthet 2000-2003, NetAcademia Kft 6 NetAcademia-tudástár Server esetén 12; minden egyes óra-megszakításkor (x86 processzorokál általában 10; multiprocesszoros rendszereknél 15 ms-ként) az id szelet értéke 3-mal csökken. Így könnyen kiszámolható, hogy egy-egy végrehajtási szál mennyi ideig használhatja a processzort. (Akit érdekel, miért pont 3-mal, az olvassa el az említett könyv idevonatkozó fejezeteit) Az optimális teljesítmény érdekében a Windows a végrehajtási szálak id szeletének értékét is megnövelheti (quantum boost), mégpedig akkor, amikor az adott végrehajtási szál ablaka az el térben van. Az alapértelmezett id szelet értéke; a boost engedélyezése, s t még a boost értéke is beállítható, mégpedig a HKLMSystemCurrentControlSetControl PriorityControlWin32PrioritySeparation
registry érték segítségével. Az érték alsó hat bitje számít, az alábbi kiosztásban: 5 4 Short / Long 3 2 Variable / Fixed 1 0 Boost érték Short / Long: A Quantum hossza. 1: hosszú; 2: rövid; a többi érték esetén az alapértelmezés érvényesül (Pro: rövid, Server: hosszú) Variable / Fixed: Legyen-e Quantum Boost ? 1: igen; 2: nem; a többi érték esetén az alapértelmezés érvényesül (Pro: igen, Server: nem) Boost értéke: ha a Quantum Boost engedélyezve van, itt adhatjuk meg a növelés szintjét (értéke 0 . 2 között mozoghat) Boost Variable Fixed 0 6 18 Short 1 12 18 2 18 18 0 12 36 Long 1 24 36 2 36 36 A lehetséges Quantum értékek táblázata A System tulajdonságlapról megnyitható Performance Options dialógus jól ismert kérdése („Optimalize performance for: Applications / Background Services”) is pontosan ezt a registry értéket módosítja, mégpedig az alábbiakra (a táblázatban szürkével jelöltük): Optimize for
Applications: Short; Variable; Boost 2 Optimize for Background Services: Long; Fixed Fülöp Miklós mick@netacademia.net A cikkben szerepl URL-ek: [1] http://www.solsemcom [2] http://mspress.microsoftcom/prod/books/4354htm Ez a dokumentum a NetAcademia Kft. tulajdona Változtatás nélkül szabadon terjeszthet 2000-2003, NetAcademia Kft 7 NetAcademia-tudástár Szálak II: Id zítés és prioritás Id zítés és prioritás Az el z számban megjelent cikk folytatásaképpen a következ oldalakon kicsit részletesebben bemutatjuk a Windows NT/2000 végrehajtási szálakat id zít rendszerét, annak szabályait. Cikkünk – az el z részhez hasonlóan – David Solomon [1] Barcelonában, a Tech.Ed 2001-en elhangzott el adása, valamint a ugyan és Mark Russinovich Inside Microsoft Windows 2000 (Third Edition) [2] cím könyvének aktuális fejezete alapján készült. Ez a könyv egyébként ajánlott, s t, kötelez olvasmány mindenkinek, aki szeretne komolyabban
foglalkozni a Windows lelkivilágával. Ez a dokumentum a NetAcademia Kft. tulajdona Változtatás nélkül szabadon terjeszthet 2000-2003, NetAcademia Kft 1 NetAcademia-tudástár Egy kis ismétlés Foglaljuk össze az el z számban leírtakat: a Windows NT/2000 (továbbiakban csak Windows, különös tekintettel arra, hogy nem a Windows 9x családról van szó) operációs rendszer szinten végrehajtási szálakat futtat. Minden végrehajtási szál valamilyen processzhez tartozik (egy processzhez akár több is); ezek a processzek képezik a tulajdonképpeni alkalmazásokat. A processz nem más, mint az általa birtokolt végrehajtási szálak részére fenntartott adminisztratív objektum és közös memóriaterület – a végrehajtási szálak id zítésében általában nem játszik szerepet. Kivételt képez ez alól a prioritás esete; az induló végrehajtási szálak kezdetben a szül processz prioritásértékét öröklik, és a felhasználói felületen is csak
a processz (és általa az összes hozzá tartozó végrehajtási szál) prioritása módosítható. A Windows 32 prioritási szintet kezel; a magasabb érték magasabb prioritást jelent. A 32 prioritási szint két f részle oszlik: az alsó félben (0-15) az úgynevezett dinamikus, a fels félben (16-31) pedig az úgynevezett valósidej prioritásértékek találhatók. A 0 prioritásértéket kötelez en a Zero Page Thread viseli (lásd a Windows memóriakezelésér l szóló cikket az el z számban). A Windows 32 prioritási szintje és a prioritásosztályok elhelyezkedése A fenti ábrán a Windows 32 prioritási szintje mellett a felhasználói felületen keresztül is elérhet , úgynevezett „prioritásosztályok” találhatók. A processzek (és rajtuk keresztül a végrehajtási szálak) prioritását ugyanis mi, a felhasználó is meghatározhatjuk és módosíthatjuk. Futás közben a Task Manager-ben jobb gombbal kattintva kiválaszthatjuk a kívánt prioritást.
Processz prioritásának módosítása futás közben a Task Manager segítségével Az egyes prioritásosztályok beállítása során a processz az el z ábrán látható középértéket kapja (a Normál prioritás középértéke például 8). A prioritás indítás el tti beállításának egyetlen módja a start parancs, amelynek paraméterként átadhatjuk a kívánt prioritásosztályt, valahogy így (lásd még: start /?): start /low notepad.exe start /abovenormal notepad.exe A processz (figyelem! nem a végrehajtási szál!) aktuális, alap (bázis) prioritásosztályát a Task Manager-ben, a Base Priority oszlopban láthatjuk, de jobban járunk ha (például) a Windows 2000 Support Tools-ból futtatjuk a Process Viewer-t (pview.exe), mert akkor nem csak a bázis prioritást, de a végrehajtási szálak aktuális (current) prioritásértékeit is Ez a dokumentum a NetAcademia Kft. tulajdona Változtatás nélkül szabadon terjeszthet 2000-2003, NetAcademia Kft 2
NetAcademia-tudástár megleshetjük. A végrehajtási szálak státuszának és prioritásának másik jó megfigyel eszköze a Performance Monitor (használatát az el z számban már bemutattuk). Az operációs rendszer magja (a kernel) valósidej prioritású végrehajtási szálakat futtat. Legyünk óvatosak a valósidej prioritás használatával, mert el fordulhat, hogy létfontosságú I/O végrehajtási szálaktól vesszük el a futási id t. Az általa elérhet végrehajtási szálak prioritását bármelyik felhasználó módosíthatja, egy korlátozással: valósidej prioritást csak az állíthat be, aki rendelkezik az „Increase scheduling priority” privilégiummal – ez alapértelmezésben csak az Administrators csoportra érvényes. Ha a prioritást módosítani próbáló felhasználó ezzel a privilégiummal nem rendelkezik, a processz valósidej helyett „High” (dinamikus) prioritásosztályba kerül. Végül: meg kell jegyeznünk, hogy miközben a valósidej
prioritásokról beszélünk, a Windows nem igazi valósidej (real-time) operációs rendszer (ld. még: [3]) A végrehajtási szálak saját prioritásukat Windows API hívásokkal módosíthatják; számos fontos alrendszer (például a rendszerszolgáltatásokat felügyel Service Manager, vagy a biztonsági alrendszer (LSASS)) eleve magasabb prioritással fut, mint az egyébként nekik kijelölt Normal osztály alapértelmezése. Alap és pillanatnyi prioritás Egy végrehajtási szál pillanatnyi prioritásértéke két részb l áll össze: A végrehajtási szál alap prioritása (base priority) A relatív prioritás (priority boost), ami az alap prioritáshoz hozzáadódik, és értéke id vel változhat A priority boost-ról kés bb még lesz szó, de azt már most elmondhatjuk, hogy a valósidej prioritásértékkel futó végrehajtási szálaknál a rendszer nem használja – ezek pillanatnyi prioritásértéke mindig megegyezik az alap prioritással (ezért hívják a nem
valósidej prioritásértékeket dinamikus prioritásnak). A végrehajtási szálak futtatásának id zítéséhez az id zít (dispatcher) mindig a pillanatnyi prioritást ellen rzi. A dispatcher várakozási sor-adatbázisa A végrehajtási szálak id zítését végz komponens, a dipatcher (ami a maga valójában nem is létezik, feladatát kernelszerte elszórtan található összetev k végzik) minden prioritásértékhez egy-egy várakozási sort tart fenn. Ezekben a várakozási sorokban találhatók a futásra kész (Ready állapotú) végrehajtási szálak. A dispatcher adatbázisát a következ képpen ábrázolhatjuk: A Dispatcher várakozási sor-adatbázisa Az ábra bal oldalán láthatók a különböz prioritásértékhez rendelt várakozási sorok (Dispatcher ready queue). Az adatbázis a feldolgozás meggyorsítása érdekében két összegz mez t is tartalmaz: A Ready summary bitmez valamely bitjének értéke azt jelzi, hogy az adott prioritású várakozási sorban
található-e futásra kész végrehajtási szál (azaz érdemes-e egyáltalán benézni a várakozási sorba) Az Idle summary bitmez pedig processzorokat tartalmaz: a bitek értéke az adott processzor szabad (idle) állapotát jelzi. Találós kérdés: legfeljebb hány processzort képes használni a jelenlegi legizmosabb Windows, a Datacenter Server? A legfontosabbak mégiscsak a várakozási sorok: amikor a Windows a következ nyertes végrehajtási szálat keresi, ezeket a várakozási sorokat ellen rzi, a legmagasabb prioritásútól a legalacsonyabbig. Ha egy várakozási sorban találunk futásra kész végrehajtási szálat, léphet futó státuszba. Ha egy a várakozási sorban egynél több furásra kész végrehajtási szál található, a dispatcher igazságos módon körbe-körbe adja majd a futási jogot (round-robin). Ne feledjük, ez az igazságosság csakis azonos prioritású végrehajtási szálak között érvényes, az alacsonyabb prioritással rendelkez kkel
szemben sokkal keményebben viselkedik a Windows: amíg magasabb prioritású szál futásra kész, bizony az alsó házakban semmi sem történik. Ennek demonstrálására készítettünk egy kis példaprogramot (a [4] címr l letölthet ): Ez a dokumentum a NetAcademia Kft. tulajdona Változtatás nélkül szabadon terjeszthet 2000-2003, NetAcademia Kft 3 NetAcademia-tudástár Harcban a processzorért: a két processz nagyjából egyszerre indult, különbség csak a prioritásukban van Az ábrán látható tesztalkalmazás egy valamire képes: számol. Teszi ezt addig, amíg a CTRL+C billenty kombináció lenyomásával meg nem állítjuk. Az stbat a start parancs segítségével gyors egymásutánban kétszer elindítja ugyanazt az alkalmazást, el ször egy alacsonyabb, majd egy magasabb prioritással. Az eredmény önmagáért beszél Ha kipróbáljuk, érdemes megfigyelni, hogy a futásid eloszlása korántsem sima: amikor néha végre az alacsonyabb prioritású
végrehajtási szál is szóhoz jut, gyors egymásutánban 15-20 sort ír a képerny re, majd újabb hosszú szünet következik. Látható, hogy a magasabb prioritású processz (és az egyetlen végrehajtási szála) több nagyságrenddel többet futhat, mint az alacsonyabb prioritású változat. Az érdekes az, hogy ez utóbbi is szóhoz jut néha nem mond ez ellent a pár sorral ezel tt említetteknek? Nos, nem: az alacsonyabb prioritású processz nyilván akkor futhatott, amikor a magasabb prioritású éppen nem volt futásra kész állapotban (például mert I/O m veletre várt), de az is lehet, hogy az operációs rendszer mentette meg az „éhhaláltól” – lást kés bb. A m köd rendszer egyik kulcsa a várakozás A végrehajtási szálak leggyakoribb állapota a várakozás (wait state). Egy szál sok mindenre várhat: I/O m velet befejezésére, másik végrehajtási szál lefutására, különféle rendszereseményekre, sült galambra (ami tíz másodperc múlva
érkezik) – ezek mindegyike annyiban hasonló, hogy a várakozás során a végrehajtási szál várakozó státuszba lép (onnan majd az adott esemény bekövetkeztekor maga a Windows lépteti vissza). A várakozó státusz pedig nem futásra kész státusz, ezért ilyenkor végre feljöhetnek a felszínre az addig fuldokló, alacsonyabb prioritású végrehajtási szálak is. Van még más eset is, amikor a Windows (a Dispatcher) újra kiértékeli, ki lehet a következ futó szál – jusson eszünkbe a felsorolás az el z számból: Új végrehajtási szál futásra kész – mert új szál jött létre, vagy tért vissza várakozó státuszból Az éppen futó végrehajtási szál elhagyja a futó státuszt – mert lejárt a számára kijelölt id szelet; mert várakozó állapotba lépett, vagy mert végleg befejezte a m ködését Valamelyik végrehajtási szál prioritása megváltozik – ha önmaga, vagy akár az operációs rendszer módosítja a szál prioritását Ha a
futó végrehajtási szál Processor Affinity értéke megváltozik Priority Boost I/O m veletek után A felhasználó felé nyújtott optimális reakcióid k kialakítása érdekében a Windows bizonyos esetekben átmenetileg megnövelheti egy-egy végrehajtási szál prioritását. Az I/O m veletet „végz ” végrehajtási szál elküldi a kérést az eszközmeghajtónak, majd a m velet befejezéséig wait state-be kerül. Amikor a m velet befejez dik, a szál újra futásra kész státuszba kerül, ráadásul a Windows átmenetileg a prioritását is megnöveli. Hogy ez a növelés milyen mérték , azt az adott I/O eszköz eszközmeghajtója határozza meg. Az ajánlott érték típusonként más és más (videó, lemez, CD-ROM, párhuzamos port: 1, hálózat, soros port: 2, billenty zet, egér: 6, hang: 8). Ez az érték mindig a szál alap prioritásához adódik hozzá és az összeg soha nem lépi át a 15-öt (valósidej prioritásnál pedig nincsen boost). A megnövelt
prioritás csak rövid ideig érvényes, minden quantumegység lejártakor a prioritásérték is csökken eggyel, egészen addig, míg a végrehajtási szál újra el nem éri az alap prioritásértéket. Priority Boost az el térben futó végrehajtási szálnak A Windows a wait state-b l visszatér , el térben futó végrehajtási szál prioritását is megnöveli, mégpedig az el z számban bemutatott Win32PrioritySeparation registry kulcs alsó két bitjén beállított értékkel (a Quantum boost-nál ez csak egy mutató volt („Boost értéke”), ezesetben viszont maga az érték számít). Ez az érték a végrehajtási szál pillanatnyi prioritásához adódik hozzá. Hasonlóképpen, további 2 boost-ot kap minden végrehajtási szál, ami ablakkezel üzenetet kap (ablak mozgatása, méretezése, stb). Priority Boost az „éhhalál” (starvation) ellen Minden operációs rendszer egyik f problémája az alábbi: tegyük fel, hogy egy 7-es prioritású szál fut; egy
11-es prioritású szál egy olyan er forrásra vár, amit éppen egy 4-es prioritású szál birtokol A számlálós példában láthattuk, hogy a nagyétk 7-es miatt a 4-es prioritású szál bizony nem lesz képes befejezni a munkáját, és elengedni az er forrást – az eredmény az, hogy a 11-es prioritású szál is éhen hal. Az ilyen helyzetek elkerülése érdekében a Windows kernel „Balance Ez a dokumentum a NetAcademia Kft. tulajdona Változtatás nélkül szabadon terjeszthet 2000-2003, NetAcademia Kft 4 NetAcademia-tudástár Set Manager” nev komponense folyamatosan ellen rzi, hogy mely végrehajtási szálak nem jutottak szóhoz az elmúlt 300 órajel-intervallumban (300x10ms = kb. 3 másodperc) Ha talál ilyet, a szegény elnyomott végrehajtási szál prioritását 15-re emeli, és dupla Quantumot ad neki (!). Ezid alatt a szál lélegzethez juthat A dupla id szelet lejárta után azonnal minden (prioritás) visszatér a régi kerékvágásba. Indítsuk
csak el újra a példaprogramocskát! Nem felt n , hogy az alacsonyabb prioritású végrehajtási szál kb. három másodpercenként jut szóhoz? :-) Természetesen ez a módszer sem tökéletes, ráadásul a Balance Set Manager (teljesítményokokból) egyszerre csak 16 elnyomott végrehajtási szálat ellen riz – de az esetek többségében ez a kis segítség elég a patthelyzetek (deadlock) elkerülésére. Többprocesszoros rendszerek Többprocesszoros rendszerben a végrehajtási szálakhoz úgynevezett processzor-affinitást rendelhetünk. Ez tulajdonképpen nem más, mint egy maszk, ami meghatározza, hogy az adott végrehajtási szál melyik processzor(ok)on futhat, és melyeken nem. Még két másik fogalmat kell tisztázni: Ideal Processor: a végrehajtási szál létrehozásakor a Windows véletlenszer en hozzárendel egy „kedvenc” processzort Last Run Processor: az a processzor, amelyen a végrehajtási szál utoljára futott Amikor egy végrehajtási szál futásra
kész állapotba lép, a Windows szabad (idle) processzort keres a számára. Ha megteheti, a végrehajtási szál ideális processzorát választja; ha az nem szabad, a last run processzort; ha pedig az sem szabad, akkor a Dispatcher adatbázisból keres egy ráér példányt. Ha nincs szabad processzor, akkor a Windows megkeresi az els , a végrehajtási szál által használható processzort, és ha azon a végrehajtási szál prioritásánál alacsonyabb prioritású szál fut (running), vagy készül a futásra (standby), akkor átveszi annak a helyét (ez a preemtion). Ha a prioritás nem elegend , a Windows nem keres másik processzort a végrehajtási szálnak, hanem azt a várakozó sorba helyezi. Amikor egy processzor felszabadul, az egyprocesszoros rendszerekkel ellentétben a Windows nem az els futásra kész végrehajtási szálat indítja, hanem azt, amelyik megfelel az alábbiak valamelyikének: Utoljára az adott processzoron futott Az ideális processzora az adott
processzor Legalább két Quantum óta futásra kész 24, vagy nagyobb a prioritása Végül Szeretnék bemutatni egy, a weben talált tanulságos szimulációt. Kattintsunk a [5] címre, és elénk tárul egy kétprocesszoros rendszer (Flash plug-in szükségeltetik), ahol követhetjük a három processz négy végrehajtási szálának futását. A végrehajtási szálak processzor-affinitást is tartalmaznak, a szimulációt a „Clock” feliratú kapcsoló nyomogatásával léptethetjük. Jó szórakozást! Fülöp Miklós mick@netacademia.net A cikkben szerepl URL-ek: [1] http://www.solsemcom [2] http://mspress.microsoftcom/prod/books/4354htm [3] http://support.microsoftcom/support/kb/articles/Q94/2/65ASP [4] http://technet.netacademianet/download/threading [5] http://www.808multimediacom/winnt/simulatorhtm Ez a dokumentum a NetAcademia Kft. tulajdona Változtatás nélkül szabadon terjeszthet 2000-2003, NetAcademia Kft 5