C# Vícevláknové aplikace
Úvod Každý proces OS má právě jedno hlavní vlákno, které funguje jako vstupní bod aplikace Vlákno jako vykonávací cesta uvnitř procesu Primárná vlákno vytváří dodatečná vlákna sekundární Vlákna mají souběžný přístup ke sdíleným datům Jmenný prostor System.Threading Typ System.Thread
.Stavy vláken (podprocesů) System.Threading.ThreadState Running Suspended Unstarted Aborted WaitSleepJoin
Pomocí klíčového slova lock Synchronizace vláken Pomocí klíčového slova lock Definujete obor příkazů, které budou mezi vlákny synchronizovány Příchozí vlákna nebudou moci přerušit aktuální vlákno a zabránit mu, aby dokončilo svou práci Klíčové slovo lock požaduje, abyste specifikovali nějaký doklad (odkaz na objekt), který musí vlákno mít, chce-li vstoupit do oboru lock Pomocí typu System.Threading.Monitor Monitor.Enter() přijímá doklad vlákna Monitor.Exit() uvolní doklad vlákna Kód uvnitř oboru zámku je zabalen do bloku try
Pomocí typu System.Threading.Interlocked Synchronizace vláken Pomocí typu System.Threading.Interlocked Ve vícevláknovém prostředí jsou bezpečné pouze atomické operace Atomických operací je velmi málo (v dokumentaci SDK) Přiřazení hodnoty do členské proměnné není atomický !!! Interlocked je vhodný pro jednoduché aritmetické operace Menší náklady než Monitor Metody System.Threading.Interlocked CompareExchanged() – otestuje 2 hodnoty na rovnost a pokud se rovnají změní jednu hodnotu na třetí hodnotu Decrement() – Bezpečně sníží hodnotu o 1 Increment() - Bezpečně zvýší hodnotu o 1 Exchange() – Bezpečně prohodí 2 hodnoty
Synchronizace vláken - příklad Lock Public void AddOne() { lock(this) { intVal++; } } Interlocked int newVal = Interlocked.Increment(ref intVal);
Pomocí atributu [Synchronization] Synchronizace vláken Pomocí atributu [Synchronization] Atribut úrovně třídy Uzamkne veškerý členský instanční kód třídy Umístí objekt do synchronizovaného kontextu Pomocí System.Threading.SpinLock Podproces by měl držet zámek co nejkratší Pomocí System.Threading.Mutex Nejtěžší typ zámku Použitelný ve více procesech Používá jedinečné jméno
Pomocí System.Threading.Semaphore Synchronizace vláken Pomocí System.Threading.Semaphore Používá se k souběžnému přístupu několika podprocesů k určitému prostředku Podproces (vlákno) do semaforu pomocí metody WaitOne() a snižuje počitadlo semaforu o jedna Pokud je počitadlo na nule, přístup podprocesů je blokován Metoda Release() zvyšuje počitadlo o jedna Těžký synchronizační objekt
Thread Pool Tvorbu vláken necháme na běhovém prostředí Použití pro jednoduché případy Thread controller přiřazuje vlákna úkolům Třída ThreadPool nám reprezentuje “zásobník” vláken, které řídí běhové prostředí Přes rozhraní sdělujeme, že bychom chtěli určitou metodu zavolat asynchronně ThreadPool je jedinečný pro proces CLR
Asynchronní delegáty Delegát jako potomek MulticastDelegate obsahuje metody BeginInvoke() a EndInvoke() public interface IAsyncResult { object AsyncState { get; } waitHandle AsyncWaitHandle { get; } bool IsCompleted { get; } … }