´ Vlakna v C#
´ r 11) Jazyk C# (seminaˇ ´ Pavel Prochazka KMI
3. prosince 2014
´ Pavel Prochazka
´ r 11) Jazyk C# (seminaˇ
´ Vlakna v C#
Motivace
I
I
I
I
I
ˇ ı jednojadrov ´ Dnes uˇz se prakticky nedelaj´ e´ procesory – pokud ´ potˇrebujeme v´ykon, mus´ıme zapojit vˇsechna jadra ˇ ˇ v´ıce vec´ ˇ ı soubeˇzneˇ – napˇr´ıklad poˇc´ıtat Casto potˇrebujeme delat ˇ umelou inteligenci na pozad´ı a pˇritom vykreslovat ´ ´ Muˇ k interferenc´ım – napˇr´ıklad jedno vlakno se ˚ ze ale dochazet ´ pokouˇs´ı celistveˇ cˇ ´ıst soubor a pˇritom jine´ vlakno ten soubor modifikuje ´ et ˇ nekter ˇ Z duvodu moˇzn´ych interferenc´ı chceme provad e´ ukony ˚ ´ ˇ nedeliteln eˇ – atomicky, k tomu slouˇz´ı synchronizaˇcn´ı primitiva ´ Vlakno je z pohledu C# metoda
´ Pavel Prochazka
´ r 11) Jazyk C# (seminaˇ
´ Vlakna v C#
´ Vlakna v C#
I I I
I
I
I
I I
Namespace System.Threading ´ Tˇr´ıda Thread reprezentuje vlakno ´ typu ThreadStart Konstruktor tˇr´ıdy Thread akceptuje delegat nebo ParameterizedThreadStart ´ ThreadStart oˇcekav ´ a´ metodu vracej´ıc´ı void bez Delegat argumentu˚ ´ ParameterizedThreadStart oˇcekav ´ a´ metodu Delegat vracej´ıc´ı void s jedin´ym argumentem typu object, lze tak pˇredat libovoln´y poˇcet argumentu˚ ´ Vlakno se spouˇst´ı metodou Start() nebo jej´ım pˇret´ızˇ en´ım ´ Start( object o ) (podle typu delegatu) ´ ´ Metoda void Abort() nasiln eˇ ukonˇcuje vlakno ´ Metoda void Join() cˇ eka´ na dokonˇcen´ı vlakna, jakmile skonˇc´ı ´ an´ ´ ı programu pokraˇcuje se ve vykonav
´ Pavel Prochazka
´ r 11) Jazyk C# (seminaˇ
´ Vlakna v C#
´ ame? ´ Ilustraˇcn´ı pˇr´ıklad – jak´y v´ystup oˇcekav
public static void PutText(){ for( int i = 0 ; i < 5 ; i++ ){ Console.WriteLine ("bar"); } }
public static void Main () { Thread oThread = new Thread (new ThreadStart(PutText)); oThread.Start (); for( int i = 0 ; i < 5 ; i++ ){ Console.WriteLine ("foo"); } oThread.Join(); }
´ Pavel Prochazka
´ r 11) Jazyk C# (seminaˇ
´ Vlakna v C#
Jeden z mnoha moˇzn´ych v´ystupu˚ – Proˇc to tak je?
foo foo foo foo bar bar bar foo bar bar
´ Pavel Prochazka
´ r 11) Jazyk C# (seminaˇ
´ Vlakna v C#
Synchronizaˇcn´ı primitiva v C# – mutex
I
I
ˇ a´ typu bool, Mutex (mutual exclusion) – je to v podstateˇ promenn ´ hodnota false ˇr´ıka, ´ zˇ e muˇ ktera´ ˇr´ıka, ˚ zeme vstoupit, hodnota ´ zˇ e uˇz nekdo ˇ true ˇr´ıka, vstoupil a tud´ızˇ se mus´ı cˇ ekat, aˇz bude volno ˇ se pomoc´ı mutexu zabranuje ˇ Nejˇcasteji v´ıcer´y pˇr´ıstup pˇr´ıstup ke ´ sd´ılenemu prostˇredku
I
Tˇr´ıda Mutex, konstruktor Mutex() nebo Mutex( bool InitiallyOwned )
I
´ Metoda ReleaseMutex () pouˇst´ı mutex – pouˇz´ıvame kdykoliv uˇz nepotˇrebujeme pracovat se sd´ılen´ym prostˇredkem, provede atomicky nastaven´ı mutexu na false Metoda WaitOne() cˇ eka´ aˇz bude mutex false, jakmile uvid´ı false atomicky nastav´ı mutex na true a pokraˇcuje se ve ´ an´ ´ ı kodu ´ vykonav
I
´ Pavel Prochazka
´ r 11) Jazyk C# (seminaˇ
´ Vlakna v C#
´ ate ´ v´ystupy? Mutex v praxi – jak´y/jake´ oˇcekav public static Mutex m1 = new Mutex (); public static void PutText(){ m1.WaitOne (); for( int i = 0 ; i < 5 ; i++ ){ Console.WriteLine ("bar"); } m1.ReleaseMutex (); } public static void Main () { Thread oThread = new Thread ( new ThreadStart(PutText)); oThread.Start (); m1.WaitOne (); for( int i = 0 ; i < 5 ; i++ ){ Console.WriteLine ("foo"); } m1.ReleaseMutex (); oThread.Join(); }
´ Pavel Prochazka
´ r 11) Jazyk C# (seminaˇ
´ Vlakna v C#
´ Proˇc? V´ystup pˇr´ıkladu s mutexem – 2 moˇzne.
1. bar bar bar bar bar foo foo foo foo foo
2. foo foo foo foo foo bar bar bar bar bar
´ Pavel Prochazka
´ r 11) Jazyk C# (seminaˇ
´ Vlakna v C#
Kl´ıcˇ ove´ slovo lock – kriticka´ sekce
I
I I
I
I
´ kodu ´ Slouˇz´ı k proveden´ı cˇ asti atomicky – tzn. vˇsechna ostatn´ı ´ vlakna programu jsou zastavena pˇri pokusu o vstup do kriticke´ sekce ´ Obvykle slouˇz´ı ke stejnemu uˇ ´ celu jako mutex Typicke´ je pouˇzit´ı pro reententrantn´ı metody – chceme zajistit, aby ´ stejnou metodu bylo moˇzne´ volat z v´ıce vlaken (napˇr´ıklad Console.WriteLine) a nedoˇslo k interenci Jak jste si mohli vˇsimnout Console.WriteLine nem´ıcha´ znaky, ´ ale vyp´ısˇ e atomicky vˇzdy cel´y ˇradek Syntaxe je lock( variable ){ BODY }
´ Pavel Prochazka
´ r 11) Jazyk C# (seminaˇ
´ Vlakna v C#
´ z, co mutex Lock v praxi – toteˇ
public static object oLock = new object (); public static void PutText(){ lock (oLock) { for (int i = 0; i < 5; i++) { Console.WriteLine ("bar"); } } }
public static void Main () { Thread oThread = new Thread (new ThreadStart(PutText)); oThread.Start (); lock (oLock) { for (int i = 0; i < 5; i++) { Console.WriteLine ("foo"); } } oThread.Join(); }
´ Pavel Prochazka
´ r 11) Jazyk C# (seminaˇ
´ Vlakna v C#
Semafory v C#
I
I
I
I
ˇ a, ´ ktere´ limituje poˇcet vlaken ´ Semafor je celoˇc´ıselna´ promenn ´ pˇristupuj´ıc´ıch ke sd´ılenemu prostˇredku ´ ´ ´ pokud semafor ma´ hodnotu 0, pˇrestav ´ a´ Semantika: vlakno cˇ eka, cˇ ekat, jakmile se hodnota zv´ysˇ ´ı ´ Kaˇzde´ vlakno kdyˇz se doˇcka´ zv´ysˇ en´ı semaforu, tak jeho cˇ ´ıslo atomicky sn´ızˇ ´ı ´ Jakmile vlakno jiˇz nepotˇrebuje semafor, uvoln´ı jej a dojde k ´ atomickemu zv´ysˇ en´ı hodnoty o 1
I
Tˇr´ıda Semaphore, konstruktor Semaphore(int initialCount, int maximalCount) Metoda WaitOne() cˇ eka´ na zv´ysˇ en´ı semaforu na nenulovou hodnotu, jakmile se doˇcka´ atomicky sn´ızˇ ´ı semafor o 1 a pokraˇcuje ´ an´ ´ ı programu ve vykonav
I
Metoda Release() atomicky inkrementuje semaforu
I
´ Pavel Prochazka
´ r 11) Jazyk C# (seminaˇ
´ Vlakna v C#
A ted’ vy
I
I
Napiˇste paraleln´ı verzi jednoho z tˇr´ıd´ıc´ıch algoritmu, ˚ pokuste se o ´ ı efektivitu maximaln´ ´ ´ CPU Paraleln´ı program srovnejte se sekvenˇcn´ım na v´ıcejadrov em a ukaˇzte, zˇ e paraleln´ı verze je rychlejˇs´ı
´ Pavel Prochazka
´ r 11) Jazyk C# (seminaˇ