Vlákna v C# - 6. díl
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama

Vlákna v C# - 6. dílVlákna v C# - 6. díl

 

Vlákna v C# - 6. díl

Google       Google       2. 10. 2008       23 669×

Dnes nás čeká poměrně krátká kapitola, a to synchronizační kontexty.

Reklama
Reklama

Kromě manuálního zamykání (jiný způsob locking jsme ani nebrali) můžeme zamykat i deklarativně, automaticky. Docílíme toho tím, že třídu odvodíme od třídy ContextBoundObject a pak na ni aplikujeme atribut Synchronization. Přikážeme tak běhovému prostředí CLR, aby zamykal automaticky:

using System;
using System.Threading;
using System.Runtime.Remoting.Contexts;

[Synchronization]
public class AutoLock : ContextBoundObject
{
    public void Demo()
    {
        Console.Write("Start...");
        Thread.Sleep(1000); // Nestane se, že by se sem dostala dvě vlákna,
        Console.WriteLine("konec"); // díky automatickému lockingu
    }
}

public class Test
{
    public static void Main()
    {
        AutoLock safeInstance = new AutoLock();
        // Zavoláme 3× metodu Demo
        new Thread(safeInstance.Demo).Start();
        new Thread(safeInstance.Demo).Start();
        safeInstance.Demo();
    }
}

CLR zajistí, že jen jedno vlákno může spustit kód uvnitř „safeInstance“. Docílí toho vytvořeným svého synchronizačního objektu, který zamkne okolo každého volání metody nebo vlastnosti ze „safeInstance“. Oblast, kterou zámek dokáže pokrýt, označujeme za synchronizační kontext.

Jak přesně tohle ale celé funguje? Klíč je v v namespace atributu Synchronization, který je System.Runtime.Remoting.Contexts. Instanci ContextBoundObject si můžeme představit jako „vzdálený“ objekt. Tím je myšleno, že všechny volané metody jsou zachyceny. Zachycení probíhá přes „prostředníka“ – když vytvoříme instanci naší třídy AutoLock, CLR vytvoří něco jako prostředníka – objekt se stejnými metodami a vlastnostmi jako AutoLock. Právě přes tohoto prostředníka se vykonává automatické zamykání. Ohledně výkonu – automatické zamykání prodlouží volání metody o pár mikrosekund.

Automatické zamykání nemůže být použito na statické členy (vždy je nutná instance, aby se mohl vytvořit prostředník), ani na třídy, které nejsou odvozené od ContextBoundObject (příkladem budiž Windows formulář odvozený od třídy Form).

Synchronizační kontext může přesáhnout rámec jednoho objektu (instance třídy). Pokud byl synchronizovaný objekt vytvořen z jiné třídy, obě třídy pak sdílejí stejný kontext (jeden velký zámek). Toto chování se dá upravit pomocí nastavení atributu Synchronization přes třídu SynchronizationAttribute (ta obsahuje několik pojmenovaných „int“ konstant, uvedených v tabulce):

Konstanta Význam
NOT_SUPPORTED Totéž, jako když nepoužijeme atribut vůbec
SUPPORTED Spojí existující kontext s právě vytvořeným, pokud žádný další neexistuje, nic se nestane
REQUIRED (výchozí) Spojí existující kontext s právě vytvořeným, pokud žádný další neexistuje, vytvoří se nový
REQUIRES_NEW Vždy vytvoří nový kontext

Takže pokud přes instanci třídy SynchronizaceA vytvoříme instanci třídy SynchronizaceB, oba budou mít svůj vlastní synchronizační kontext (pokud je SynchronizaceB deklarována jako v příkladu níže).

[Synchronization (SynchronizationAttribute.REQUIRES_NEW)]
public class SynchronizaceB : ContextBoundObject {}

Je logické, že čím větší rozsah kontextu, tím je vše snadnější pro správu, ale jsme více omezení možnostmi. Na druhou stranu – při použití hodně kontextů zase hrozí „deadlocky“ (pro připomenutí – zamezení práce dvou vláken navzájem):

[Synchronization]
public class Deadlock : ContextBoundObject
{
    public Deadlock Other;
    public void Demo()
    {
        Thread.Sleep(1000);
        Other.Ahoj();
    }
    void Ahoj()
    {
        Console.WriteLine("ahoj");
    }
}

public class Test
{
    static void Main()
    {
        var dead1 = new Deadlock();
        var dead2 = new Deadlock();
        dead1.Other = dead2;
        dead2.Other = dead1;
        new Thread(dead1.Demo).Start();
        dead2.Demo();
    }
}

Protože je každá instance třídy Deadlock vytvořená uvnitř třídy Test (bez atributu Synchronization), každá instance bude mít svůj synchronizační kontext, a tím pádem i svůj lock. Když se dva objekty různě volají navzájem, jako to dělají v příkladu výše, netrvá dlouho a dojde k deadlocku. Na tento „jev“ je nutné dávat si trochu pozor, u automatického lockingu nemusejí být příčiny vždy tak zřejmé.

Reentrancy

S tímto pojmem jsme se setkali ve třetím díle, označuje metodu, která je absolutně thread-safe – jedno vlákno ji může zavolat hned po zavolání jiným vláknem bez jakýchkoliv neočekávaných efektů atd. Poměrně často mají pojmy „thread-safe“ a „reentrant“ stejný význam.

Avšak nedají se úplně zaměnit. Pravá „reentrant“ metoda vznikne, když atribut Synchronization rozšíříme o klíčové slovo true:

[Synchronization(true)]

Pokud běh aplikace opustí na chvíli ten „svůj“ kontext, dojde k jeho dočasnému zaniknutí. Toto by zabránilo v příkladu nahoře deadlockům! Na druhou stranu, kterékoliv vlákno je pak schopné zavolat kteroukoliv metodu v označené třídě („znovu-vstupovat“ do kontextu; reentering), následkem toho ale mohou být další problémy, kterým se celou tu dobu snažíme vyhnout.

Protože je atribut [Synchronization(true)] aplikován na úrovni třídy, každá metoda v označené třídě se tak stává náchylná na „volné“ volání!

Uvedli jsme si několik příkladů, které ukazují některé nevýhody automatického lockingu. Pokud ho použijeme, můžou vyjít na povrch problémy, které by jindy ani nevznikly. Díky tomu je ve složitějších aplikacích výhradně používané manuální zamykání.

Příště nás čeká téma, které spousta z vás očekává – přístup k prvkům na formuláři pomocí metod Control.Invoke, Control.BeginInvoke a hlavně třídy BackgroundWorker.

Zdroj: http://www.albahari.com/threading/part2.html#_Synchronization_Contexts

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
(fotka) Jakub KottnauerJakub studuje informatiku na FIT ČVUT, jeho oblíbenou platformou je .NET.
Web     Twitter     Facebook     LinkedIn    

Nové články

Obrázek ke článku Blockchain & Bitcoin konference

Blockchain & Bitcoin konference

V pátek 19. 5. 2017 se v pražském konferenčním centru Andel’s konala Blockchain & Bitcoin konference. Řada odborníků a podnikatelů v oboru blockchainu a kryptoměn představila možnosti budoucího směřování tohoto oboru. Speakeři většinou rusky mluvící provenience prezentovali řešení svých firem založená na technologii blockchainu.

Reklama
Reklama
Obrázek ke článku Malware KONNI se úspěšně skrýval 3 roky. Odhalil ho bezpečnostní tým Cisco Talos

Malware KONNI se úspěšně skrýval 3 roky. Odhalil ho bezpečnostní tým Cisco Talos

Bezpečnostní tým Cisco Talos odhalil celkem 4 kampaně dosud neobjeveného malwaru, který dostal jméno KONNI. Ten se dokázal úspěšně maskovat od roku 2014. Zpočátku se malware zaměřoval pouze na krádeže citlivých dat. Za 3 roky se ale několikrát vyvinul, přičemž jeho současná verze umožňuje útočníkovi z infikovaného počítače nejenom krást data, ale i mapovat stisky na klávesnici, pořizovat screenshoty obrazovky či v zařízení spustit libovolný kód. Pro odvedení pozornosti oběti zasílali útočníci v příloze také obrázek, zprávu a výhružkách severokorejského režimu či kontakty na členy mezinárodních organizací.

Obrázek ke článku Pouze jedna z deseti lokálních firem ví o pokutách plynoucích z GDPR

Pouze jedna z deseti lokálních firem ví o pokutách plynoucích z GDPR

Trend Micro, celosvětový lídr v oblasti bezpečnostních řešení a VMware, přední světový dodavatel cloudové infrastruktury a řešení pro podnikovou mobilitu, oznámily výsledky výzkumu mezi českými a slovenskými manažery zodpovědnými za ochranu osobních údajů, který zjišťoval, jak jsou připraveni na nové nařízení o ochraně osobních údajů (GDPR). Většina firem v České republice a na Slovensku nad 100 zaměstnanců je již s novým nařízením GDPR obeznámena. Výzkum provedený ve spolupráci s agenturou Ipsos ukázal, že téměř 8 firem z 10 o nařízení ví, přičemž jeho znalost je o něco vyšší na Slovensku (89 %) než v České republice (69 %).

Obrázek ke článku Vyděračský software Locky se vrací, tváří se jako potvrzení platby, odhalil tým Cisco Talos

Vyděračský software Locky se vrací, tváří se jako potvrzení platby, odhalil tým Cisco Talos

Jeden z nejznámějších ransomwarů, Locky, se vrací. Po většinu roku 2016 patřil mezi nejrozšířenější vyděračské softwary. Ke svému šíření využíval emailové kampaně s infikovanými přílohami. Ransomware Locky byl rozesílán prostřednictvím botnetu (internetový robot zasílající spamy) Necurs. Jeho aktivita na konci roku 2016 téměř upadla a spolu s ní i šíření ransomwaru Locky. Před několika týdny se Necurs opět probudil a začal posílat spamy nabízející výhodný nákup akcií. Dne 21. dubna zaznamenal bezpečnostní tým Cisco Talos první velkou kampaň ransomwaru Locky prostřednictvím botnetu Necurs za posledních několik měsíců.

loadingtransparent (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();
Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032017 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý