Folyamat- és szálkezelés Microsoft Windows 2000/XP/2003/Vista

Hasonló dokumentumok
Folyamat- és szálkezelés Microsoft

Folyamat- és szálkezelés Microsoft Windows 2000/XP/2003/Vista

C# Szálkezelés. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) C# Szálkezelés / 21

Párhuzamosság a modern operációs rendszerekben

Párhuzamos programozás.net környezetben

Miklós Árpád, BMF NIK, 2007

Kölcsönös kizárás, atomicitás, szemafor.

Párhuzamos programozás: folyamatok

Párhuzamos programozás: folyamatok

Vé V g é r g e r h e a h j a tá t s á i s s z s ál á ak a Runnable, Thread

Processzusok (Processes), Szálak (Threads), Kommunikáció (IPC, Inter-Process Communication)

Processzusok (Processes), Szálak (Threads), Kommunikáció (IPC, Inter-Process Communication)

A párhuzamos végrehajtás alapjai

Operációs rendszerek. Az Executive és a kernel Policy és mechanizmusok szeparálása Executive: policy - objektum kezelés Kernel: mechanizmusok:

Programozási nyelvek és módszerek Java Thread-ek

Operációs rendszerek. Az NT folyamatok kezelése

Concurrency in Swing

Szenzorhálózatok programfejlesztési kérdései. Orosz György

Windows ütemezési példa

Task-alapú párhuzamosítás C# környezetben

Operációs rendszerek Folyamatok 1.1

Szoftvertechnológia alapjai Java előadások

Konkurens TCP Szerver

(kernel3d vizualizáció: kernel245_graph.mpg)

Programozási technológia 2.

OPERÁCIÓS RENDSZEREK 1. PROCESSZKEZELÉS

Objektum Orientált Programozás. 11. Kivételkezelés 44/1B IT MAN

Ütemezés (Scheduling),

C# nyelv alapjai. Krizsán Zoltán 1. Objektumorientált programozás C# alapokon tananyag. Általános Informatikai Tanszék Miskolci Egyetem

Matematikai és Informatikai Intézet. 4. Folyamatok

BME MOGI Gépészeti informatika 4.

Johanyák Zsolt Csaba: Ugráló gomb oktatási segédlet Copyright 2008 Johanyák Zsolt Csaba

Operációs rendszerek. Folyamatok ütemezése

Ütemezés (Scheduling),

Operációs Rendszerek II.

Operációs rendszerek II. Folyamatok ütemezése

Grafikus felhasználói felület 3.

... S n. A párhuzamos programszerkezet két vagy több folyamatot tartalmaz, melyek egymással közös változó segítségével kommunikálnak.

Uniprogramozás. várakozás. várakozás. Program A. Idő. A programnak várakoznia kell az I/Outasítások végrehajtására mielőtt továbbfuthatna

C#, OOP. Osztályok tervezése C#-ban

Feladatok (task) kezelése multiprogramozott operációs rendszerekben

Végrehajtási szálak - kiegészítések. Szinkronizálás, érvénytelenített metódusok helyettesítése

Operációs rendszerek. 3. előadás Ütemezés

Eseménykezelés. Szoftvertervezés és -fejlesztés II. előadás. Szénási Sándor.

Bánsághi Anna

9. MPI

Java Programozás 1. Gy: Java alapok. Ismétlés ++

Párhuzamosság. Java a párhuzamosítást több féle képpen támogatja.

Helyes-e az alábbi kódrészlet? int i = 1; i = i * 3 + 1; int j; j = i + 1; Nem. Igen. Hányféleképpen lehet Javaban megjegyzést írni?

OOP #14 (referencia-elv)

Programozás BMEKOKAA146. Dr. Bécsi Tamás 5. előadás

Szoftvertechnolo gia gyakorlat

Operációs Rendszerek II.

Programozás BMEKOKAA146. Dr. Bécsi Tamás 1. Előadás

Pénzügyi algoritmusok

SQLServer. SQLServer konfigurációk

A C# PROGRAMOZÁSI NYELV

Az UPPAAL egyes modellezési lehetőségeinek összefoglalása. Majzik István BME Méréstechnika és Információs Rendszerek Tanszék

Kalapácsvetés 2016 szöveges

CREATE TABLE student ( id int NOT NULL GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name varchar(100) NOT NULL, address varchar(100) NOT NULL )

2. Folyamatok. Operációs rendszerek. Folyamatok. Bevezetés Folyamatkezelés multiprogramozott rendszerekben. Folyamatok modellezése

Java bevezet o Kab odi L aszl o Kab odi L aszl o Java bevezet o

INFORMATIKAI ALAPISMERETEK

Informatika terméktervezőknek

BME MOGI Gépészeti informatika 13.

Thermo1 Graph. Felhasználói segédlet

Programozási nyelvek Java

Elosztott rendszerek

OOP és UML Áttekintés

Programozási nyelvek Java

Számítástechnika I. BMEKOKAA152 BMEKOKAA119 Infokommunikáció I. BMEKOKAA606. Dr. Bécsi Tamás

Segédanyag: Java alkalmazások gyakorlat

Szoftvertechnológia alapjai Java előadások

Autóipari beágyazott rendszerek. Komponens és rendszer integráció

Java Programozás 4. Gy: Java GUI. Tipper, MVC kalkulátor

Objektumorientált programozás C# nyelven

3. Határozza meg és írja ki a minta szerint, hogy a forrásállományban hány kémiai elem felfedezési adatai

Operációs rendszerek MINB240

Tartalom. Operációs rendszerek Bevezetés CPU ütemezés. Középtávú ütemezés. Hosszútávú ütemezés

Termelő-fogyaszt. fogyasztó modell

Operációs rendszerek MINB240

Balogh Ádám Lőrentey Károly

Haladóprogramozás (C#) , I. félév BMF NIK

Java Programozás 11. Ea: MVC modell

Java gyakorlat feladatai e s megolda sai ( )

Bevezetés a párhuzamos programozási koncepciókba

Az operációs rendszer szerkezete, szolgáltatásai

Java Programozás 9. Gy: Java alapok. Adatkezelő 5.rész

Objektumorientált programozás C# nyelven

GenerikusOsztály<objektumtípus> objektum = new GenerikusOsztály<objektumtípus>();

Vizuális és eseményvezérelt programozás , II. félév BMF NIK

Operációs rendszerek MINB240

INFORMATIKAI ALAPISMERETEK

Operációs rendszerek. Folyamatok kezelése a UNIX-ban

Programozás BMEKOKAA146. Dr. Bécsi Tamás 8. előadás

Széchenyi István Egyetem. Programozás III. Varjasi Norbert

LabView Academy. 4. óra párhuzamos programozás

Segédanyag: Java alkalmazások gyakorlat

Programozási alapismeretek beadandó feladat: ProgAlap beadandó feladatok téma 99. feladat 1

1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben?

Átírás:

Folyamat- és szálkezelés Microsoft Windows 2000/XP/2003/Vista Definíciók és folyamatmodell Folyamatok és szálak kezelése Ütemezési kérdések Többprocesszoros és többmagos rendszerek miklos.arpad@nik.bmf.hu Folyamatmodell (1) Definíciók Folyamat ( process ) Az operációs rendszerek programokat hajtanak végre Kötegelt rendszerek: feladatok ( job ) Interaktív rendszerek: felhasználói programok ( task ) A folyamat egy adott program dinamikus, a virtuális memóriában elhelyezkedő, élő példánya) Fő adminisztrációs egység (állapotinformáció tár) Erőforrások aktuális állapota (memória, fájlok, objektumkezelők, hálózati kapcsolatok...) Processzoridő alapú elszámolást is lehetővé tesz Hagyományosan az ütemezés alapegysége A Windows nál a szál ( thread ) az ütemezés alapegysége 2 1

Folyamatmodell (2) Definíciók Szál ( thread ) A Windows nál az ütemezés alapegysége A processzorokon ténylegesen a szálak futnak, nem a folyamatok Folyamaton belüli állapotadminisztrációs egység Processzorok, ütemezés, I/O műveletek állapotai Nincs saját címtere Az egy folyamathoz tartozó szálak egymással osztoznak a folyamat címterén A többszálú működés problémákat vethet fel Összehangolási pontok (randevú, kilépés) Adatkezelés Szálspecifikus adatok kezelése Szál szempontjából globális adatok kezelése 3 Folyamatmodell (3) A Windows nál alkalmazott négyszintű modell 1. szint feladat ( job ) Folyamatkészlet Szabályozhatók a benne lévő folyamatok paraméterei CPU idő, munkakészlet, biztonsági beállítások stb. Kötegelt feldolgozáshoz ideális 2. szint folyamat ( process ) A szokásos értelemben vett (teljes kontextusú) folyamat Egy adott program dinamikus, a virtuális memóriában elhelyezkedő, élő példánya, lásd korábban 4 2

Folyamatmodell (4) A Windows nál alkalmazott négyszintű modell 3. szint szál ( thread ) Ütemezési alapegység Lehetséges állapotok: 0: Indítható ( initialized ) 1: Futásra kész ( ready ) 2: Futó ( running ) 3: Készenléti ( standby ) 4: Befejezett ( terminated ) 5: Várakozó ( waiting ) 6: Átmeneti ( transition ) 4. szint vékonyított szál ( fiber ) Initialized (0) Transition (6) Ready (1) Kézi ütemezés a létrehozó szál kontextusán belül Szálak állapotátmeneti diagramja Kernelverem kilapozva Preempció Standby (3) Preempció, kvantum vége Waiting (5) Original image 2000 2005 David A. Solomon and Mark Russinovich Running (2) Önként lemondás Terminated (4) 5 Folyamatok és szálak kezelése (1) Folyamatok létrehozása és megszüntetése Folyamatok létrehozása 3 részben fut le 3 különböző kontextusban (létrehozó folyamat, Win32 alrendszer, létrejövő folyamat) CMD.EXE NTVDM.EXE program.exe MS DOS.bat,.cmd Win16 Milyen típusú a program? Win32 Win32 (64 bites Windows) OS/2 1.x POSIX MS DOS.exe,.com,.pif program.exe (speciális WoW64 támogatással) OS2.EXE POSIX.EXE NTVDM.EXE Original image 2000 2005 David A. Solomon and Mark Russinovich 6 3

Folyamatok és szálak kezelése (2) Váltások a processzorok birtoklásában Kontextusváltás Mindig szálak között történik T 1 szál Megszakítás vagy rendszerhívás T 2 szál Futó Állapotmentés (TCB 1 ) Állapotbetöltés (TCB 2 ) Futásra kész vagy várakozó Futásra kész vagy várakozó Futó Megszakítás vagy rendszerhívás Állapotmentés (TCB 2 ) Állapotbetöltés (TCB 1 ) Futó Futásra kész vagy várakozó Original image 2000 2005 David A. Solomon and Mark Russinovich 7 Ütemezés (1) A Windows rövid távú ütemezési politikája Eseményalapú ütemezés Nincs központi ütemező modul a kernelben Az ütemezés alapvetően szálszinten történik Minden folyamathoz tartozik legalább egy szál Preemptív, prioritásos, körbeforgó algoritmus Időszelet alapú kötelező preempció Mindig a legmagasabb prioritású futásképes szál fut Külön várakozó sor minden prioritási szinthez 8 4

Ütemezés (2) A Windows általános ütemezési politikája Preempció (futásmegszakítás) esetei: Lejár a szál időszelete Újraütemezéskor az addig futó szál időszelete 3 mal csökken Elindul egy nagyobb prioritású szál Az előző az időszelet megmaradt részét később visszakapja A szál eseményre kezd várni A szál önként feladja a futás jogát Szigorú értelemben véve nem minősül preempciónak Külső megszakítás következik be Megszűnik a szál 9 Ütemezés (3) Prioritások Prioritások kezelése Kétszintű rendszer (folyamatok és szálak; 0 31 ig) 0 15 16 31 High Realtime Below Normal Idle Above Normal Normal 4 6 8 10 13 24 10 5

Ütemezés (3) Prioritások Prioritások kezelése Kétszintű rendszer (folyamatok és szálak; 0 31 ig) Folyamatok prioritási osztályai Realtime High Above Normal Normal Below Normal Idle Time Critical 31 15 15 15 15 15 Szálak prioritási szintjei Highest Above Normal Normal Below Normal Lowest 26 25 24 23 22 15 14 13 12 11 12 11 10 9 8 10 9 8 7 6 8 7 6 5 4 6 5 4 3 2 Idle 16 1 1 1 1 1 Lapnullázó szál: 0 Üresjárati szál: 1 Windows Vista: multimédia ütemezőszolgáltatás (MMCSS) 11 Ütemezés (4) Időszeletek A körbeforgó ütemezés következményei A processzorintenzív alkalmazásoknak kedvez Az időszelet erősen befolyásolja az észlelt teljesítményt Az időszelet ( quantum ) hossza A Normál prioritási osztálynál módosítható Hossz, típus, előtérben lévő alkalmazás kiemelése Beállítások: 1 időszelet = 3*x rendszerórajel ütem Újraütemezésnél 3 mal csökken az időszelet hossza Windows Vista: a megszakításban töltött idő (igazságos módon) már nem csökkenti az időszelet hosszát 12 6

Ütemezés (5) Beépített kompenzációs mechanizmusok Prioritás növelése ( priority boosting ) I/O művelet befejezésekor Képernyőmeghajtó & lemezmeghajtók: 1 Soros port & hálózat: 2 Billentyűzet & egér: 6 Hangeszközök: 8 Várakozó állapotból kilépéskor Eseményre, szemaforra stb. várakozás: 1 Előtérben lévő folyamat befejezte a várakozást: 2 A szál által várt GUI (ablak) esemény beérkezésekor: 2 Régóta készenlétben álló szálaknál 2 időszeletnyi időre 15 re emeli a prioritást Időszelet módosítása ( quantum stretching ) A prioritásnövelés idejére megkétszereződik az időszelet 13 Több processzor kezelése (1) Ütemezés egynél több, illetve többmagos CPU esetén Négyféle kernelmegvalósítás: NTOSKRNL.EXE egy processzor ACPI Uniprocessor System rendszereken régebbi CPU knál (Pentium I/II/III, AMD K5/K6/Athlon) NTKRNLPA.EXE egy processzor, fizikai címkiterjesztés ACPI Uniprocessor System rendszereken modern CPU knál (Pentium IV/M, Core/Core 2, AMD Athlon XP/64/Opteron) NTKRNLMP.EXE több / többmagos processzor ACPI Multiprocessor System rendszereken régebbi CPU knál NTKRPAMP.EXE több / többmagos processzor, fizikai címkiterjesztés ACPI Multiprocessor System rendszereken modern CPU knál 14 7

Több processzor kezelése (2) Ütemezés egynél több CPU, illetve többmagos CPU esetén Eltérések az egyprocesszoros ütemezéshez képest A legmagasabb prioritású szálak egyike kerül futó állapotba valamelyik processzor(mag)on Terheléskiegyenlítés csak szálszinten Szimmetrikus elosztás (nincs főprocesszor és alárendelt processzorok ) Windows 2003 Server: minden processzorhoz (maghoz) külön ready állapotú várakozósorok 15 Több processzor kezelése (3) Ütemezés egynél több, illetve többmagos CPU esetén Processzor kiválasztása futtatandó szálhoz Processzoraffinitás: meghatározza, hogy mely processzorokon futhat egy egy folyamat (a hozzá tartozó szálak) Ideális processzor A szál indulásakor véletlenszerűen kijelölt processzor Következő processzorok Azon processzorok, amelyeken a szál korábban már futott Futtatandó szál kiválasztása processzorhoz Az ütemező igyekszik azonos processzoron tartani a szálakat 16 8

SzPE (C#) 2007 2008, II. félév BMF NIK Párhuzamos programozás:.net szálak használata Szálak kezelése Új szálak indítása, szálak felfüggesztése, állapotvezérlése és leállítása, szálak prioritási szintjei Előtér és háttérszálak, ThreadPool szálak Szinkronizáció A szinkronizáció alapfogalmai, versenyhelyzet és holtpont fogalma Kölcsönös kizárás biztosítása, a lock utasítás, szálak bevárása és randevúja miklos.arpad@nik.bmf.hu Szálak A szálak elsődleges célja a folyamatokon belüli párhuzamosítás A folyamatok adminisztrációja és váltása igen erőforrásigényes művelet, viszont az általuk nyújtott elszigetelés szintje egy programon belül csaknem mindig szükségtelen. Ezt az ellentmondást oldják fel a szálak, amelyek elszigetelést nem nyújtanak, gyors párhuzamos végrehajtást azonban igen. P 1 folyamat T 11 szál T 13 szál P 2 folyamat T 22 szál P 3 folyamat T 31 szál T 12 szál T 21 szál T 23 szál T 24 szál A.NET keretrendszer támogatja a szálak kezelését is A keretrendszer kihasználja az operációs rendszer száltámogatását, de a.net szálak és az operációs rendszer szálai között nem feltétlenül létezik 1:1 megfeleltetés (egy valódi szálon a keretrendszer több szála is futhat). 18 9

A többszálúság megvalósítási lehetőségei System.Threading.Thread osztály Lehetővé teszi szálak egyenkénti létrehozását, azonosítását, állapotvezérlését és megszüntetését. Kezelése egyszerű, viszont sok programozói munkát és pontosságot igényel. System.Threading.ThreadPool osztály Gyakran ismétlődő, rövid ideig tartó, erősen párhuzamos műveletekhez rendelkezésre álló szálkészlet, melynek használatával megtakarítható a szálak egyenkénti létrehozásának és megszüntetésének időigényes munkája. Kezelése egyszerű és hatékony, de a szálak egyéni identitását nem biztosítja. System.ComponentModel.BackgroundWorker osztály (később) A felhasználói felület kezelésének és a háttérben elvégzendő, esetenként igen sokáig tartó műveletek végrehajtásának szétválasztására szolgál. Kezelése igen kényelmes (az állapotváltozásokról események útján értesíti a felhasználó osztályt), ám korlátozott funkcionalitása miatt kevés célra alkalmas. 19 Threading névtér A System.Threading névtér a következő szálfeladatokat oldja meg: Futás idejű kontroll szinkronizáció thread pooling System.Threading fontosabb típusai: Alaposztályok: Thread és ThreadPool Felsorolások: TreadState és ThreadPriority Osztály: Monitor Kivételek: ThreadAbortException és ThreadInterruptedException delegate ThreadStart, WaitCallback, TimerCallback, IOCompletionCallback, 20 10

Szálak kezelése (kivonatos referencia) System.Threading.Thread osztály Metódusok Start() Suspend(), Resume() Abort() GetHashCode() Sleep() Join() Tulajdonságok CurrentCulture, CurrentUICulture IsBackground IsThreadPoolThread ManagedThreadID Name Priority ThreadState Szál indítása Szál felfüggesztése, illetve folytatása Szál leállítása Szál azonosítójának lekérése Várakozás a megadott időintervallum elteltéig Várakozás az adott szál befejeződésére A szálhoz tartozó aktuális kultúra, illetve a szálhoz tartozó felhasználói felület kiválasztott nyelve Az adott szál háttérszál vagy előtérszál* Az adott szál a ThreadPool egyik szála e A szál egyedi azonosítója A szál megnevezése A szál prioritása (fontossági szintje) A szál aktuális állapota(i) * A programok futása véget ér, ha az utolsó előtérszál is lefutott (az esetleg még futó háttérszálak ekkor automatikusan megszűnnek). 21 Thread osztály public sealed class Thread { public Thread(ThreadStart start); public ThreadPriority Priority {get; set; public ThreadState ThreadState {get; public bool IsAlive {get; public bool IsBackground {get; set; public void Start(); public static void Sleep(int time); public void Suspend(); public void Resume(); public void Join(); public void Interrupt(); public void Abort(); public static void ResetAbort(); Konstruktor, paramétere: ThreadStart delegate Aktuális állapot Háttér Szál vezérlő metódusok public static Thread CurrentThread {get; Az aktuálisan futó szál 22 11

ThreadStart, ThreadPriority és ThreadState public delegate void ThreadStart(); public sealed class Thread { public Thread( ThreadStart start); public ThreadPriority Priority {get; set; public ThreadState ThreadState {get; public enum ThreadPriority { Highest, AboveNormal, Normal, BelowNormal, Lowest, public enum ThreadState { Unstarted, Running, Background, WaitSleepJoin, SuspendRequested, Suspended, AbortRequested, Stopped 23 Thread példa ThreadStart delegálthoz metódus using System.Threading; public class ThreadExample { public static void RunT0() { for ( int i=0; i<10000; i++) { Console.Write( "x ); Thread.Sleep(100); //Thread készítése delegate to method RunT0 and starting it public static void Main(string[] args) { // Main thread starts a new thread which runs RunT0 method Thread t0 = new Thread( new ThreadStart(RunT0)); t0.start(); 24 12

Példa új szál indítására 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 using System; using System.Threading; class Program { static void Main(string[] args) { Console.WriteLine("Szál közvetlen létrehozása"); Console.WriteLine("Főszál (sorszáma: {0)", Thread.CurrentThread.GetHashCode()); Thread newthread = new Thread(ThreadMethod); //.NET 1.1 esetén: Thread newthread = new Thread(new ThreadStart(ThreadMethod)); newthread.name = "Új szál"; newthread.start(); newthread.join(); static void ThreadMethod() { Console.WriteLine("{0 (sorszáma: {1)", Thread.CurrentThread.Name, Thread.CurrentThread.GetHashCode()); ThreadExamples\Program.cs 25 Thread példa using System; using System.Threading; class Printer { char ch; int sleeptime; public Printer(char c, int t) {ch = c; sleeptime = t; public void Print() { for (int i = 0; i < 100; i++) { Console.Write(ch); Thread.Sleep(sleepTime); class Test { static void Main() { Printer a = new Printer('.', 10); Printer b = new Printer('*', 100); new Thread(a.Print).Start(); new Thread(b.Print).Start(); Két szál, melyek folyamatosan a képernyőre írnak példánymetódussal 26 13

Előtér és háttér szálak Az előtér és háttér szálak közötti különbségek Amíg előtér szál fut, addig a program nem terminál A háttér szál futása nem gátolja meg a program terminálását Az IsBackground tulajdonsággal állítható Thread bgthread = new Thread(new ThreadStart( )); bgthread.isbackground = true; 27 Thread állapotok példa Thread t = new Thread(P); Console.WriteLine("name={0, priority={1, state={2", t.name, t.priority, t.threadstate); t.name = "Worker"; t.priority = ThreadPriority.BelowNormal; t.start(); Thread.Sleep(1); Console.WriteLine("name={0, priority={1, state={2", t.name, t.priority, t.threadstate); t.suspend(); Thread.Sleep(1); Console.WriteLine("state={0", t.threadstate); t.resume(); Console.WriteLine("state={0", t.threadstate); t.abort(); Thread.Sleep(1); Console.WriteLine("state={0", t.threadstate); Output name=, priority=normal, state=unstarted name=worker, priority=belownormal, state=running state=suspended state=running state=stopped public enum ThreadState { Unstarted, Running, Background, WaitSleepJoin, SuspendRequested, Suspended, AbortRequested, Stopped 28 14

Thread állapotdiagram Suspended safepoint reached SuspendRequested t.suspend Unstarted t.start Running t.resume end of thread method t.abort Stopped AbortRequested Exception caught, finally processed Thread.Sleep other.join Wait(obj) time over other joined Pulse(obj) t.interrupt t.abort WaitSleepJoin 29 Megvárás példa (Join) using System; using System.Threading; class Test { static void P() { for (int i = 0; i < 20; i++) { Console.Write('-'); Thread.Sleep(100); static void Main() { Thread t = new Thread(P); Console.Write("start"); t.start(); t.join(); // waits for t Console.WriteLine("end"); Output: start--------------------end 30 15

Abort kezelése példa Az Abort speciális kivételt dob, amelyet kezelni lehet a metódusban using System; using System.Threading; class Test { static void P() { try { try {try { while (true) ; catch (ThreadAbortException) { Console.WriteLine("-- inner aborted"); catch (ThreadAbortException) { Console.WriteLine("-- outer aborted"); finally { Console.WriteLine("-- finally"); static void Main(string[] arg) { Thread t = new Thread(P); t.start(); Thread.Sleep(1); t.abort(); t.join(); Console.WriteLine("done"); Output -- inner aborted -- outer aborted -- finally done 31 ThreadPools ThreadPool szálak halmazát képes kezelni Regisztrált feladathalmaz hatékony kezelése Rövid idejű feladatok, inaktívak egy ideig Hátrány: Az alkalmazói programnak nincs kontrollja (nem lehet pl. prioritást szabályozni) 32 16

Szálak kezelése (kivonatos referencia) System.Threading.ThreadPool osztály Metódusok QueueUserWorkItem() Metódus végrehajtása egy ThreadPool szálon GetAvailableThreads() A rendelkezésre álló ThreadPool szálak számának lekérdezése GetMaxThreads(), GetMinThreads() Maximálisan rendelkezésre álló, illetve minimálisan életben tartott ThreadPool szálak számának lekérdezése SetMaxThreads(), SetMinThreads() Maximálisan rendelkezésre álló, illetve minimálisan életben tartott ThreadPool szálak számának beállítása RegisterWaitForSingleObject() Várakozás erőforrásra vagy időzítőre 33 ThreadPool osztály public sealed class ThreadPool { public static void GetAvailableThreads(out int w, out int aios); public static void GetMaxThreads(out int w, out int aios); A munka és IO szálak száma A munka és IO szálak maximális száma public static bool QueueUserWorkItem( WaitCallback task); public static bool QueueUserWorkItem( WaitCallback task, object state); A task regisztrálása WaitCallback delegateként public delegate void WaitCallback(object state ); WaitCallback delegate 34 17

ThreadPool példaváz Feladat definíció public static void WorkerTask(object state) { while ( ) { // do something short Thread.Sleep( ); // then sleep A munka és IO szálak száma int maxworkers, availworkers; int maxios, availios; ThreadPool.GetMaxThreads(out maxworkers, out maxios); ThreadPool.GetAvailableThreads(out availworkers, out availios); Új feladatot adunk a poolba object state = ; ThreadPool.QueueUserWorkItem(new WaitCallback(WorkerTask), state); 35 Feladat (3) Készítsünk konzolos alkalmazást, amely a ThreadPool osztály segítségével 4 külön szálon jeleníti meg az egyes szálak által folyamatosan növelt saját belső számláló értékét! A program valamilyen megoldással biztosítsa a szálak által kiírt adatok vizuális elkülönítését! Ötletek: A QueueUserWorkItem() metódus paramétere egy WaitCallback típusú képviselő, amely visszatérési érték nélküli, egyetlen ( object típusú) paraméterrel rendelkező metódusokat képes tárolni A ThreadPool szálai is azonosíthatók a ManagedThreadID tulajdonsággal (azonban előfordulhat például, hogy egy szál által megkezdett feladatot egy másik szál folytat és egy harmadik szál fejez be) A szálak közötti váltások megfigyeléséhez érdemes sok munkát adni az egyes szálaknak és néha várakoztatni őket (ennek legegyszerűbb módja a Thread osztály statikus Sleep() metódusa) 36 18

Megoldás (3) ThreadExamples\Program.cs 37 Szinkronizáció A szinkronizáció olyan, párhuzamos szálak (vagy folyamatok) együttműködését megvalósító mechanizmus, amely minden körülmények között biztosítja a szálak (vagy folyamatok) által végzett műveletek szemantikai helyességét A párhuzamosan futó szálak kommunikációjához szinte biztosan szükség van közös erőforrások (memória, portok, I/O eszközök, fájlok) használatára. Ha ezek állapotát egy szál módosítja, de közben más szálak is hozzájuk férnek, akkor az utóbbi szálak könnyen hibás vagy félkész adatokhoz juthatnak. Az alapprobléma: bármely két utasítás végrehajtása között előfordulhat, hogy más szálak kapnak lehetőséget az előző szál által is kezelt közös adatok olvasására vagy módosítására Egyprocesszoros rendszereknél az operációs rendszer ütemezője (a szálak közötti váltás) ad erre lehetőséget, többprocesszoros rendszereknél pedig a valódi (fizikai) párhuzamosság miatt még gyakrabban merül fel a probléma. Ennek elkerülését szolgálják elsősorban a különböző szinkronizációs megoldások (másik, ezzel összefüggő céljuk az időzítések összehangolása). 38 19

Szinkronizáció kölcsönös kizárással Kritikus szakasz ( critical section ) A programokon belül megjelölt kritikus kódrészletek soros végrehajtását biztosítja több párhuzamos szál esetén is..net osztályok: System.Threading.Monitor (és a C# lock utasítása), System.Threading.Mutex, System.Threading.ReaderWriterLock Szemafor ( semaphore ) A kritikus szakasz általánosítása (többpéldányos erőforrások esetén egyszerre több szál belépését is lehetővé teszi)..net osztály: System.Threading.Semaphore (.NET 2.0) Atomi végrehajtás ( interlocked execution ) Egyes egyszerű műveletek oszthatatlan végrehajtását biztosítja (igen gyors)..net osztály: System.Threading.Interlocked Csővezeték ( pipe ) Olvasható és írható FIFO puffer, amely szükség szerint várakoztatja az igénylőket (az ún. termelő fogyasztó probléma megoldására készült). 39 Szinkronizáció bevárással (randevú) Esemény ( event ) Két kódrészlet soros végrehajtását biztosítja úgy, hogy a B kódrészletet végrehajtó szál megvárja, amíg az A kódrészletet végrehajtó szál végez feladatával, illetve lehetőséget ad alkalmankénti vagy rendszeres jelzésre is..net osztályok: System.Threading.Thread, System.Threading.AutoResetEvent, System.Threading.ManualResetEvent Időzítő ( timer ) Relatív vagy abszolút időhöz való igazodást tesz lehetővé..net osztályok: System.Windows.Forms.Timer, System.Timers.Timer, System.Threading.Timer Időzítők jellemzői Windows.Forms.Timer Pontosság ~10 ms Futtatás saját szálon Csak egyszeri aktiválás Beállítható első aktiválás Vizuális komponens + Platformfüggetlen Timers.Timer ~100 ns (!) + + Threading.Timer ~1 ms + + + + 40 20

Szinkronizációs elemek I. Egyszerű blokkoló metódusok * Konstrukció Sleep Join Cél Adott ideig blokkol Másik szál végét várja Lock koló konstrukciók, kritikus szakasz * Konstrukció lock Monitor (Enter(), Exit()) Mutex Semaphore Cél Csak egy szál férhet az erőforráshoz, vagy a kódrészhez Csak egy szál férhet az erőforráshoz, vagy a kódrészhez Csak egy szál férhet az erőforráshoz, vagy a kódrészhez. Meghatározott számú szál férhet az erőforráshoz, vagy a kódrészhez Cross process + + Sebesség + + * Ha a szálnak várakoznia kell ezen konstrukciók miatt, akkor un. blokkolt és állapota: WaitSleepJoin. Ilyenkor nem kap ütemezést! 2008. március 10. miklos.arpad@nik.bmf.hu 41 Szinkronizációs elemek II. Szignál konstrukciók * Konstrukció EventWaitHandle Wait, Pulse ** Cél Engedélyezi, hogy a szál várjon, amíg egy másik száltól szignált nem kap Engedélyezi, hogy a szál várjon, amíg egy beállított blokkoló feltétel teljesül Cross process + Sebesség * Ha a szálnak várakoznia kell ezen konstrukciók miatt, akkor un. blokkolt és állapota: WaitSleepJoin. Ilyenkor nem kap ütemezést! ** A Pulse egyirányú kommunikáció: nincs visszajelzés. Azt sem tudhatjuk, hogy a Wait nél mennyivel később szabadul fel a blokkolás. Használjunk jelző flag et! Nem blokkoló szinkronizációs elemek Konstrukció Interlocked volatile Cél Nem blokkoló atomi végrehajtást biztosít Lokkon kívül, biztonságos, nem blokkoló hozzáférést biztosít bizonyos mezőkhöz Cross process Sebesség 42 ++ ++ 21

Kölcsönös kizárás lock utasítás lock(variable) Statement Példa: class Account { // this class is a monitor long val = 0; public void Deposit(long x) { lock (this) { val += x; // only 1 thread at a time may execute this statement public void Withdraw(long x) { lock (this) { val -= x; A Lock bármilyen objektumra állítható, gyakran hibásan a this t használják private static object staticsynchroot = new object(); private object instancesynchroot = new object();... public static void StaticFunction() { lock (staticsynchroot ) {... critical region... public void InstanceFunction() { lock (instancesynchroot ) {... critical region... 43 Példa szinkronizációra (a lock utasítás) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 using System; using System.Threading; class Program { private static int counter = 0; private static object lockobject = new Object(); static void Main(string[] args) { Thread t1 = new Thread(ThreadMethod); t1.start(); Thread t2 = new Thread(ThreadMethod); t2.start(); A lock utasítás nélkül a metódus private static void ThreadMethod() sorosan (egy szálon futtatva) { helyesen működik, párhuzamosan lock (lockobject) (több szálon) azonban nem { counter++; Thread.Sleep(500); Console.WriteLine("A számláló állása: " + counter); Figyelem: SOHA ne írjunk le az alábbiakra hasonlító kódot: lock (this) vagy lock (typeof(program)) 44 22

A szinkronizáció két alapvető nehézsége Versenyhelyzet ( race condition ) Párhuzamos futtatás esetén a közösen használt erőforrásokhoz történő hozzáférés szabályozatlansága veszélyezteti a program helyes működését. Az előző példa a lock utasítás nélkül jól illusztrálja a versenyhelyzet fogalmát. Holtpont ( deadlock ) Akkor léphet fel holtpont, ha több szál több erőforráshoz kíván hozzáférni, miközben egyes erőforrásokat lefoglalva tartanak (tehát már beléptek egy erőforráshoz tartozó kritikus szakaszba, ott viszont várakozniuk kell, hogy hozzájuthassanak egy másik szükséges erőforráshoz). Példa: 1 lock (a) 2 { 3 // feldolgozás 4 lock (b) 5 { 6 // feldolgozás 7 8 1. szál 1 2 3 4 5 6 7 8 lock (b) { // feldolgozás lock (a) { // feldolgozás 2. szál 45 Monitor osztály A Monitor osztály alapszintű szinkronizációt biztosít public sealed class Monitor { public static void Enter(object obj); public static bool TryEnter(object obj); public static void Exit(object obj); public static void Wait(object obj); public static bool Pulse(object obj); public static void PulseAll(object obj); Az obj részére lock kolást próbál biztosítani és blokkol Az obj részére lock kolást próbál biztosítani és visszatér Feloldja a lock kolást Várakozás állapotba hozza a szálat és elengedi a lock ot Felébreszti a következő obj ra váró szálat Felébreszti az összes obj ra váró szálat lock a Monitor rövid formája: lock (obj) { Monitor.Enter(obj) try { finally { Monitor.Exit(obj) 46 23

Monitor használata Enter blokkol, ha a lock kolás nem biztosítható TryEnter blokkolás nélkül próbál lock kolni; hamissal tér vissza, ha nem elérhető a lock kolás Enter: blokkolással! public class MonitorExample { private Queue lpt; public void AddElemBlocking (object elem) { try { Monitor.Enter (lpt.syncroot); lpt.enqueue (elem); catch (Exception e) { finally { Monitor.Exit (lpt.syncroot); TryEnter: blokkolás nélkül public bool AddElemNonBlocking (object elem) { try { if (! Monitor.TryEnter (lpt.syncroot)) return false; lpt.enqueue (elem); catch (Exception e) { finally { Monitor.Exit (lpt.syncroot); return true; 47 Wait és Pulse A Wait és Pulse segítségével a szálak szinkronizálhatók A lock kolás elengedése és várakozás ébredésre public static void Wait(object obj); public static bool Wait(object obj, int millies); Az obj re váró következő, vagy összes szál felébresztése public static bool Pulse(object obj); public static void PulseAll(object obj); lock (obj) {... Monitor.Wait(obj);... lock (obj) {... Monitor.Pulse(obj);... 48 24

Wait és Pulse elvi példa Thread A Thread B lock(v) { lock(v) {...... 1 Monitor.Wait(v); Monitor.Pulse(v);... 3... 2 5 4 1.A eléri lock(v) tés lock kol, mert a kritikus régió szabad 6 2.A eléri Wait utasítást, aludni megy és felengedi a lock ot 3.B eléri lock(v) tés lock kol, mert a kritikus régió szabad 4.B eléri a Pulse tés felébreszti A t. (Lehetséges kontextusváltás A és B között, de nem szüségszerű) 5.A lock ot szeretne kapni, de nem tud, mert B még kritikus régióban van 6.A kritikus régió végén B felengedi a lock ot; A tovább futhat 49 Wait és Pulse Megjegyzés Wait(v) és Pulse(v) csak lock(v) vel (Monitorral) zárolt utasításban jelenhet meg. A Pulse(v) és a felébresztett szál folytatása között más szálak futhatnak, amelyek időközben megpróbálták megkapni a lock ot (tehát a Pulse által szignált feltétel nem biztosan igaz, amikor a felébresztett szál visszatér a Wait után!) Ezért a Wait metódust egy ciklusba kell helyezni, ami folyamatosan teszteli a feltételt: while (condition false) Monitor.Wait(v);... make condition true; Monitor.Pulse(v); PulseAll(v) felébreszt minden szálat, amely v re vár, de közülük csak egy folytatja futását. A többinek várnia kell, amíg a lock ot fel nem engedi az előző szál. Ekkor a következő szál a kritikus régióba léphet. 50 25

Wait és Pulse szinkronizált puffer példa public class Buffer { const int size = 16; char[ ] buf = new char[size]; int head = 0, tail = 0, n = 0; public void Put(char ch) { lock(this) { while (n == size) Monitor.Wait(this); buf[tail] = ch; tail = (tail + 1) % size; n++; Monitor.Pulse(this); Ha a termelő gyorsabb: Put Put Put Get Put Get... thread 1 Lock buffer to add a character While buffer is full, release lock and wait Wake up waiting threads public char Get() { lock(this) { while (n == 0) Monitor.Wait(this); char ch = buf[head]; head = (head + 1) % size; n--; Monitor.Pulse(this); return ch; thread 2 Lock buffer to retrieve character While buffer is empty, release lock and wait Wake up waiting threads Ha a fogyasztó a lassabb: Put Get Put Get 51... Szinkronizált puffer 3 Get szál eléri az üres puffert Belépnek a kritikus régióba és aludni mennek, mert üres a puffer Egy Put szál érkezik, Kritikus régióba lép; Elhelyezi adatát és jelez: PulseAll G1 G2 G3 Első belépés Kritikus régió Mindenl Get szál felébred; Az első a kritikus régióba lép, kiolvassa az adatot és kilép G1 G2 G3 Várakozás A többiek ismét várakozási állapotba kerülnek, mert üres a puffer P1 G1 G2 G3 G1 G2 G3 G2 G3 Ismételt belépés 52 26

Feladat (4) Készítsünk többszálú konzolos alkalmazást, amely egy időigényes számítási műveletet 2 szállal párhuzamosan végeztet el! A műveletet most egy közösen használt számláló folyamatos növelése jelentse, és egy szálnak kb. 2 3 másodpercig tartson a művelet elvégzése! Amennyiben szükséges, gondoskodjon a szálak szinkronizációjáról is! A program valamilyen megoldással biztosítsa a szálak által kiírt adatok vizuális elkülönítését! Ötletek: A Stopwatch osztály metódusai segítségével egyszerűen mérhető az eltelt (relatív) idő Először egy egyszerű megvalósítással döntsük el, szükség van e szinkronizációra, majd ha úgy ítéljük meg, hogy igen, akkor használjuk a lock utasítást vagy a Monitor osztály statikus Enter(), illetve és Exit() metódusát Szinkronizáció esetén a jobb teljesítmény érdekében igyekezzünk a lehető legrövidebbre venni a kritikus szakaszt 53 Feladat (5) Készítsünk konzolos alkalmazást, amelynek csak egy példánya futhat egyszerre. Használjunk Mutexet a megvalósításhoz! (Készítsünk el ugyanilyen funkciójú alkalmazást processzek lekérdezésével és vizsgálatával is!) Ötletek: A Mutex name paramétere egyedi legyen. Pl. bmfnik.hu MUTEXv01 A Mutex WaitOne és ReleaseMutex metódusait használjuk. Az első metódus várakozási paramétert is kaphat, amit felhasználva megjeleníthetünk pl. hibaüzenetet. Processzek esetében a GetCurrentProcess és a GetProcesses metódusok segíthetnek. 54 27

Feladat (6) Készítsünk konzolos alkalmazást, amely Semaphore segítségével egy garázs működését prezentálja. A garázs kapacitása 10, benne a főnököknek foglalt helyek száma 5. A kocsik (szálak) véletlen ideig állnak a garázsban és összesen 20 tulajdonos jogosult a használatra. Az érkezéskor és induláskor írjuk ki, hogy melyik autó óhajt beállni, illetve elmenni. Ötletek: Osztályszintű Semaphore WaitOne, illetve Release metódusát használjuk. A szálfüggvény paraméterként kapja meg, hogy mely autó szeretne beállni. A parkolást Sleep metódussal valósítsuk meg. 55 Feladatok (7) Készítsünk konzolos alkalmazást, amely az Interlocked osztály atomi metódusait teszteli! Ötletek: Egy utasítás atomi, ha egyetlen oszthatatlan instrukcióként fut. Az egyszerű 32 bites adatok olvasása (32 bites CPU n) atomi. Olvasást és írást kombináló utasítások nem atomiak (pl. az x++ nem atomi). Az Interlocked statikus metódusai nem blokkolnak és sosem kell az ütemező átütemezésére várniuk (szemben pl. a lock kal). Az Interlocked osztály atomi operációkat biztosít ref paraméterként átadott int, vagy long típusokra. Teszteljük az Increment, Decrement, Add, Read, Exchange és CompareExchange metódusok működését egy long típusú ref paraméter használatával. 56 28

Feladatok (8) Készítsünk konzolos alkalmazást, amelynek elindított mindkét szálja egymásnak ötször üzenetet küld. Az üzenet megérkezésekor az egyik szál azt írja ki a konzolra: ThreadPing, a másik ThreadPong! Ötletek: Használjuk a Monitor osztály Pulse és Wait metódusait osztályszintű lock objektummal (static objectball). 57 Feladatok (9) Készítsünk demonstrációs alkalmazást, amely az AutoResetEvent és a ManualResetEvent működése közti különbséget mutatja be! Az elindított szál küldjön szignált a főszálban adott ideig, többször várakozó ResetEventeknek. Írjuk ki, hogy jel hatására milyen állapotba kerültek. Ötletek: Használjuk az osztályok Set és WaitOne és Reset metódusait. A szálfüggvényben Sleeppel szabályozzunk. 58 29

Feladatok (11) Töltsünk fel stringlistát két szál segítségével 100 100 elemmel és az eredményt jelenítsük meg képernyőn. Ötletek: Használjuk a Collections névtér List generikus típusát: List<string> list = new List<string>(), illetve az Add metódust. Két szál AutoResetEventekkel kommunikáljon egymással, amíg az egyik speciális üzenetet nem küld. Az üzenet osztályszintű string legyen. Ötletek: Hogyan védjük az üzenetet? 59 BackgoundWorker szálak (rövid referencia) System.ComponentModel.BackgroundWorker osztály Metódusok RunWorkerAsync() CancelAsync() ReportProgress Tulajdonságok IsBusy CancellationPending WorkerSupportsCancellation WorkerReportsProgress Események DoWork ProgressChanged RunWorkerCompleted Háttérszál indítása Háttérszál leállítása Háttérszál folyamatjelzése A háttérszál aktív e (éppen fut e) Leállítás folyamatban (leállási kérelem érkezett) A háttérszál kérés esetén képes idő előtti leállásra A háttérszál képes folyamatjelzésre Kezelője a háttérben futtatandó metódus* A háttérszál folyamatjelzését fogadó esemény A háttérszál futása befejeződött * Ez a metódus (a Windows UI megvalósítási modellje következtében) közvetlenül nem érintkezhet a felhasználói felület elemeivel. Ezek szükséges frissítését és állapotmódosításait a ProgressChanged és a RunWorkerCompleted eseménykezelőkben lehet elvégezni. 60 30

Feladat (12) Készítsünk Windows alkalmazást, amely időigényes műveletet futtat a háttérben, a felhasználói felülettől független szálon! A program legyen képes a művelet indítására és menet közbeni biztonságos megszakítására, a háttérben futó művelet állapotát pedig folyamatjelzővel jelezze! Ötletek: Célszerű a BackgroundWorker osztály segítségével megoldani a feladatot A háttérben futó szál a ReportProgress() metódussal jelezheti az előrehaladást (ezt az adatot a ProgressChanged esemény második paraméterében kapja meg a megfelelő eseménykezelő metódus) A művelet megszakítását csak akkor kíséreljük meg, ha valóban fut (ez az IsBusy tulajdonság vizsgálatával állapítható meg) A háttérben futó művelet végén a RunWorkerCompleted esemény kezelője a második paraméterben kap információt a műveletről (véget ért e vagy megszakítás miatt fejeződött be, mi a végeredmény, történt e hiba stb.) 61 Megoldás (4) BackgroundWorker 62 31

Irodalomjegyzék (alapismeretek) C. Nagel, B. Evjen, J. Glynn, M. Skinner, K. Watson, A. Jones: Professional C# 2005 Kiadó: Wiley Publishing, Inc., 2006 ISBN: 978 0 7645 7534 1 Web: http://www.wiley.com/, http://www.wrox.com/ Nyelv: angol Terjedelem: 1540 oldal Folyamatok kezelése: 14 16., 413. o. Szálkezelés: 349 368. o. Microsoft Corp., Visual Studio Developer Center Szálkezelés a.net keretrendszerben: http://msdn2.microsoft.com/en us/library/3e8s7xdd(vs.80).aspx 63 Irodalomjegyzék (magasszintű ismeretek) Albert I., Balássy Gy., Charaf H., Erdélyi T., Horváth Á., Levendovszky T., Péteri Sz., Rajacsics T.: A.NET Framework és programozása Kiadó: Szak Kiadó, 2004 ISBN: 963 9131 62 8 Web: http://www.szak.hu/ Nyelv: magyar Terjedelem: 868 oldal Párhuzamos programozás: 585 607. o. Folyamatok kezelése: 608 613. o. Szálkezelés és szinkronizáció: 614 648. o. J. Richter: CLR via C#, Second Edition Kiadó: Microsoft Press, 2006 ISBN: 978 0 7356 2163 3 Web: http://www.wintellect.com/ Nyelv: angol Terjedelem: 736 oldal Szálkezelés és szinkronizáció: 585 648. o. 64 32

33