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

 
Hledat
Vybavení pro Laser Game
Spuštěn Filmový magazín
Laser Game Brno
Laser Game Ostrava

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

Google       Google       2. 10. 2008       25 945×

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

Nové články

Obrázek ke článku Konference: Moderní informační systémy podporují automatizaci

Konference: Moderní informační systémy podporují automatizaci

Současná situace v šíření onemocnění Covid-19 klade na řadu firem nové nároky a mnohé z nich jsou nyní více než kdy jindy závislé na nejmodernějších informačních technologiích. Proto i v oblasti podnikových informačních systémů vidíme rostoucí důraz na automatizaci nebo na důslednou integraci. Také o těchto trendech se bude mluvit na konferenci Firemní informační systémy, která se koná 24.9.2020 v pražském Kongresovém centru Vavruška na Karlově náměstí.

Reklama
Reklama
Obrázek ke článku Nebezpečí ukrytá v USB: z nuly na škvarek za pět sekund

Nebezpečí ukrytá v USB: z nuly na škvarek za pět sekund

Za cenu šesti dolarů lze celkem bez obtíží koupit nový, líbivě vyhlížející flash disk. Přidaná hodnota, které se vám spolu s ním dostane, už tak moc líbivá není. To, co se před pár sekundami tvářilo jako externí disk, se po připojení k počítači změní v důmyslné elektrické křeslo, které vaše zařízení v onen příslovečný škvarek promění za pár sekund. Cílovou skupinou pro koupi takových zařízení by mohli být záškodníci, kteří by tímto způsobem osnovali pomstu třeba vůči záletnému partnerovi. 

Obrázek ke článku Znalosti, dovednosti i prestižní titul MBA: Jde to i moderně a online

Znalosti, dovednosti i prestižní titul MBA: Jde to i moderně a online

Snad nikdy není špatná příležitost na investici do hodnotného vzdělání. Obzvlášť v případě, že absolvent dovede teoretické poznatky přetavit v praktické dovednosti, využitelné při řešení problémů i v komunikaci. Právě na to se specializuje studijní program MBA Řízení informačních technologií, vyučovaný na Business Institutu.

Obrázek ke článku Coding Bootcamp Praha: Obor IT krize nepoznamenala, žádaní jsou weboví vývojáři

Coding Bootcamp Praha: Obor IT krize nepoznamenala, žádaní jsou weboví vývojáři

Pandemie Covid-19 otřásla trhem práce v základech. Dopady krize pocítilo celkově až 45 % zaměstnanců. Není divu, že čím dál větší jistotu přináší obor IT. Ten zůstal krizí téměř nepoznamenán a při nutnosti začít dělat věci na dálku se ještě více ukázalo, jak moc mnohé firmy kvalitní IT potřebují. Do IT nyní přicházejí začátečníci, kteří v něm vidí lukrativní budoucnost a jistotu, ale i freelanceři a zaměstnanci z oborů zasažených krizí

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