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

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       27 677×

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

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
Jakub studuje informatiku na FIT ČVUT, jeho oblíbenou platformou je .NET.
Web     Twitter     Facebook     LinkedIn    

Nové články

Obrázek ke článku Stavebnice umělé inteligence 1

Stavebnice umělé inteligence 1

Článek popisuje první část stavebnice umělé inteligence. Obsahuje lineární a plošnou optimalizaci.  Demo verzi je možné použít pro výuku i zájmovou činnost. Profesionální verze je určena pro vývojáře, kteří chtějí integrovat popsané moduly do svých systémů.

Obrázek ke článku Hybridní inteligentní systémy 2

Hybridní inteligentní systémy 2

V technické praxi využíváme často kombinaci různých disciplín umělé inteligence a klasických výpočtů. Takovým systémům říkáme hybridní systémy. V tomto článku se zmíním o určitém typu hybridního systému, který je užitečný ve velmi složitých výrobních procesech.

Obrázek ke článku Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Vedení týmu v oboru informačních technologií se nijak zvlášť neliší od jiných oborů. Přesto však IT manažeři čelí výzvě v podobě velmi rychlého rozvoje a tím i rostoucími nároky na své lidi. Udržet pozornost, motivaci a efektivitu týmu vyžaduje opravdu pevné manažerské základy a zároveň otevřenost a flexibilitu pro stále nové výzvy.

Obrázek ke článku Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Za poslední rok se podoba práce zaměstnanců změnila k nepoznání. Především plošné zavedení home office, které mělo být zpočátku jen dočasným opatřením, je pro mnohé už více než rok každodenní realitou. Co ale dělat, když se při práci z domova ztrácí motivace, zaměstnanci přestávají komunikovat a dříve fungující tým se rozpadá na skupinu solitérů? Odborníci na personalistiku dali dohromady několik rad, jak udržet tým v chodu, i když pracovní podmínky nejsou ideální.

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý