1 / 31

Fonalak . NET-ben

Fonalak . NET-ben. Krizsán Zoltán. Mikor, miért használjuk?. Ha az algoritmus sokáig dolgozik, d e el akarjuk kerülni a „fagyást”. Kisebb a költsége, mint az új folyamatnak. Programozás szempontjából is könnyebb, mint az IPC (fájl, osztott memória, …). Thread osztály. Létrehoz, elindít

Download Presentation

Fonalak . NET-ben

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Fonalak .NET-ben Krizsán Zoltán

  2. Mikor, miért használjuk? • Ha az algoritmus sokáig dolgozik, • de el akarjuk kerülni a „fagyást”. • Kisebb a költsége, mint az új folyamatnak. • Programozás szempontjából is könnyebb, mint az IPC (fájl, osztott memória, …)

  3. Thread osztály • Létrehoz, • elindít • szálat

  4. Tulajdonságok • IsAliveGets a value indicating that the current thread is currentlyexecuting. • IsBackgroundGets or sets whether the thread runs as a backgroundthread. • IsThreadPoolThreadGets whether this thread is a thread in the thread pool. • ManagedThreadIdGets a number to identify the current thread. Not the sameas the operating system’s thread ID. • Name Gets or sets a name associated with the thread. • Priority Gets or sets the priority of the thread. • ThreadStateGets the ThreadStatevalue for the thread.

  5. Metódusok • Abort Raises a ThreadAbortExceptionon the thread to indicate thatthe thread should be aborted. • Interrupt Raises a ThreadInterruptedExceptionwhen a thread is in ablocked state (ThreadState.WaitSleepJoin).If the threadnever blocks, the interruption never happens. • Join Blocks the calling thread until the thread terminates. • Resume Deprecated. Do not use. • Start Sets a thread to be scheduled for execution. • Suspend Deprecated. Do not use.

  6. Fonál létrehozása • Definiáljunk egy metódust! (nincs vé, nincs paraméter) • Hozzunk létre egy ThreadStartdelegátum példányt! • Hozzunk létre egy új Threadpéldányt megadva az előző delegátumot! • Hívjuk meg a start metódust!(A fonálba fut a 1. metódus, majd leáll.)

  7. Fonál létrehozás példakód 1 static void SimpleWork() { Console.WriteLine("Thread: {0}", Thread.CurrentThread.ManagedThreadId); } ThreadStartoperation = new ThreadStart(SimpleWork); Thread theThread = new Thread(operation); theThread.Start(); 2 3 4

  8. Több fonál létrehozása ThreadStart operation = new ThreadStart(SimpleWork); for (int x = 1; x <= 5; ++x) { Thread theThread = new Thread(operation); theThread.Start(); }

  9. Több fonalas alkalmazás működése • Fő fonál (main thread) létrehozza a munka fonalakat (workingthread), nyilvántartja azokat, amelyek a kiegészítő munkákat végzik. • Grafikát, vezérlőket csak a fő szálból lehet használni! • Amikor a fő szálnak szüksége van az eredményekre Join minden munka szálra a főszálból!

  10. Fonál prioritás • Highest The highest priority • AboveNormalHigher priority than Normal • Normal The default priority • BelowNormalLower than Normal • Lowest The lowest priority

  11. Fonalak létrehozása adat(ok)al • ThreadStarthelyettParameterizedThreadStartdelegátum használata. • A paraméter Object típusú, cast-olni kell!(as, is operátor) • A paraméter aktuális értékét a Start metódusnak kell adni!theThread.Start("Hello");

  12. Fonál leállítás • Hívjuk a Thread.Abortmetódust! • Ennek hatására a szálban a ThreadAbortException kivétel dobódik! • Vagy elkapjuk, vagy nem, de a fonál leáll!

  13. Kritikus szekció • Az Abort metódus megszakítja a normál futást, ami következtében inkonzistens lehet az alkalmazásunk. • Ezt elkerülendő használjuk a kritikus szakaszt. • Ezt nem szakíthatja meg a rendszert. Thread.BeginCriticalRegion(); SomeClass.IsValid = true; SomeClass.IsComplete = true; Thread.EndCriticalRegion();

  14. Futási környezet - Execution Context • Minden szálhoz tartoznak adatok: • biztonsági, • kultúra, • tranzakció • Elérni a ExecutionContextstatikus metódusaival lehet azokat. • Egy rendszer szintű szál kezeli ezeket az információkat (teljesítmény szükséglet). • Felfüggesztés : AsyncFlowControlflow = ExecutionContext.SuppressFlow() • Visszaállítás: ExecutionContext.RestoreFlow();

  15. Adat megosztás fonalak között • Interlocked • lock{} • Mutex • …

  16. Példakód adat felülírásra public class Counter{ public static int Count; static void UpdateCount() { for (int x = 1; x <= 10000; ++x) { Counter.Count= Counter.Count + 1; } } }

  17. Szálak futtatása ThreadStart starter = new ThreadStart(UpdateCount); Thread[] threads = new Thread[10]; for (int x = 0; x < 10; ++x) { threads[x] = new Thread(starter); threads[x].Start(); } for (int x = 0; x < 10; ++x) { threads[x].Join(); }

  18. Eredmény • Hyper-Threading processzoroknál az eredmény nem 100,000 • Mert az írás, olvasás nem atomi! • Counter.Count++ művelet: • Betöltik a változó értékét egy regiszterbe. • Növelik a regiszter értékét. • Új érték vissza a változóba.

  19. Megoldás Interlocked osztály használata. static void UpdateCount() { for (int x = 1; x <= 10000; ++x) { Interlocked.Increment(ref Counter.Count); } }

  20. 2 számláló esete public void UpdateCount() { Interlocked.Increment(ref _count); if (Count % 2 == 0){ Interlocked.Increment(ref _evenCount); } } • Újabb probléma: a 2. számláló rossz lesz • Hiszen ugyanazt a szálat beengedi. • Nem az összetett művelet védett csak a 2 kölün-külön!

  21. lock szekció használata public void UpdateCount() { lock (this) { _count = _count + 1; if (Count % 2 == 0) // An even number { _evenCount = _evenCount + 1; } } }

  22. Monitor osztály (2. mo.) public void UpdateCount(){ Monitor.Enter(this); try{ _count = _count + 1; if (Count % 2 == 0) // An even number { _evenCount = _evenCount + 1; } } finally{ Monitor.Exit(this); } }

  23. Monitor statikus metódusai • Több lehetőség adódik a segítségével! • EnterCreates an exclusive lock on a specified object • ExitReleases an exclusive lock on a specified object • TryEnterAttempts to create an exclusive lock on a specified object;optionally supports a timeout value on acquiring the lock • WaitReleases an exclusive lock, and blocks the current threaduntil it can re-acquire the lock

  24. A szinkronizáció problémája • Problémákat old meg, de újat vezet be:holtpont(deadlock) • 2 erőforrás (1,2) 2 szál (A,B)A lokkolja 1-est és ugyanekkor B lokkolja 2-est • majd ezután kellene A-nak a 2es és B-nek az 1es • Mivel esek már lokkoltak mindkettő a másik által foglalt erőforrásra vár.

  25. Példakód holtpontra class Deadlocker{ object ResourceA = new Object(); object ResourceB = new Object(); } • public void First(){ • lock (ResourceA){ • lock (ResourceB){ • Console.WriteLine("First"); • } • } • } • public void Second(){ • lock (ResourceB){ • lock (ResourceA){ • Console.WriteLine("Second"); • } • } • }

  26. Fonalak indítása Deadlocker deadlock = new Deadlocker(); ThreadStartfirstStart = new ThreadStart(deadlock.First); ThreadStartsecondStart = new ThreadStart(deadlock.Second); Thread first = new Thread(firstStart); Thread second = new Thread(secondStart); first.Start(); second.Start(); first.Join(); second.Join();

  27. Megoldás • Monitor.TryEnteregy timeout érték múlva lemond a lokkolási kéréséről és kilép a saját lock-ból. • Csökkentsük a legkisebbre a lokkolt kódot. Csökkent a lokkolási idő, így a holtpont kialakulásának esélye.

  28. ReaderWriterLock • Különbséget teszt olvasási és írási lock között. • Olvasási beenged többet is, de írásiba csak 1 et. • Ha írják, nem lehet olvasni. • UpgradeToWriterLock, DowngradeFromWriterLock

  29. ReaderWriterLock használata ReaderWriterLockrwLock = new ReaderWriterLock(); int counter = 0; try{ rwLock.AcquireReaderLock(100); rwLock.AcquireWriterLock(1000); try{ Console.WriteLine(counter); Interlocked.Increment(ref counter); } finally{rwLock.ReleaseReaderLock();} } catch (ApplicationException){ Console.WriteLine("Failed to get a Lock"); }

  30. Mutex MutextheMutex = null; try // Try and open the Mutex{ theMutex= Mutex.OpenExisting("MYMUTEX"); } catch (WaitHandleCannotBeOpenedException){ // Cannot open the mutex because it doesn't exist } if (theMutex == null){ theMutex= new Mutex(false, "MYMUTEX"); } //használat if (theMutex.WaitOne(1000, false)) // wait 1 second for lock{ }

  31. Aszinkron metódus hívás byte[] buffer = new byte[100]; string filename = string.Concat(Environment.SystemDirectory, "\\mfc71.pdb"); FileStreamstrm = new FileStream(filename,FileMode.Open, FileAccess.Read, FileShare.Read, 1024,FileOptions.Asynchronous); IAsyncResultresult = strm.BeginRead(buffer, 0, buffer.Length, null, null); // Közben csinálhatunk bármit intnumBytes = strm.EndRead(result);// amikor kell az eredmény strm.Close(); Console.WriteLine("Read {0} Bytes", numBytes); Console.WriteLine(BitConverter.ToString(buffer));

More Related