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

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

 

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

Google       Google       26. 8. 2008       27 323×

Dnes si povíme o metodách Interrupt a Abort, v druhé části pak o vlastnosti ThreadState.

Odblokovat vlákno můžeme dvěma způsoby:

  • Pomocí metody Thread.Interrupt
  • Pomocí metody Thread.Abort

K zavolání jedné z těchto metod musí dojít v jiném vlákně, než v tom zablokovaném – zablokované vlákno není schopné dělání čehokoliv, je prostě zablokované.

Interrupt

Zavolání metody Interrupt na zablokované vlákno násilně ukončí jeho zablokování a zároveň vytvoří výjimku ThreadInterruptedException, stejně jako v následujícím příkladu:

class Program
{
    static void Main()
    {
        Thread t = new Thread(delegate()
        {
            try
            {
                Thread.Sleep(Timeout.Infinite);
            }
            catch (ThreadInterruptedException)
            {
                Console.Write("Násilně ");
            }
            Console.WriteLine("odblokováno!");
        });

        t.Start();
        t.Interrupt();
    }
}

Tento kód vypíše do konzole text „Násilně odblokováno!“, je tedy vidět, že výjimka ThreadInterruptedException je skutečně vytvořena.

Když zavoláme Interrupt na vlákno, které není zablokované, tak se účinek této metody pozdrží, dokud k zablokování nedojde. Pak se opět vytvoří výjimka ThreadInterruptedException a všechno pokračuje stejně jako v kódu výše. Díky tomuto opatření nemusíme použít tento test:

if ((vlakno.ThreadState & ThreadState.WaitSleepJoin) > 0)
    vlakno.Interrupt();

Který by ani nebyl thread-safe kvůli možnému přerušení mezi podmínkou a voláním Interrupt.

Ovšem přerušení blokace vlákna s sebou nese určitá rizika – pokud na to není kód stavěný, může dojít k narušení běhu aplikace. Bezpečné by to bylo, kdybychom věděli, v jaké fázi své činnosti se vlákno zrovna nachází, a podle toho bychom mohli práci synchronizovat. Že jste to slovo už někde slyšeli? Ano, v předminulém díle byla tabulka různých metod synchronizace a mezi nimi byly i signalizační konstrukce. A ty právě slouží k vyřešení tohoto problému. O těch ale zase příště.

Abort

Tato metoda má podobný účinek jako metoda Interrupt, až na pár odlišností. Místo ThreadInterruptedException dochází k vytvoření výjimky ThreadAbortException. Navíc, tato výjimka je vyhozena ještě jednou na konci catch bloku (vlákno se snaží ukončit se, co to jen jde), pokud v tomto bloku nezavoláme metodu Thread.ResetAbort. Mezitím má metoda ve vlastnosti ThreadState uloženou hodnotu AbortRequested.

Největší rozdíl oproti Interrupt je ale v tom, jak se tato metoda chová, když ji zavoláme na vlákno, které není zablokované. Zatímco Interrupt čeká, než k zablokování dojde, Abort vyhodí výjimku v momentě zavolání. Následky mohou být komplikovanější, proto se na ně zaměříme až v posledních dílech seriálu.

Stav vlákna (ThreadState)

Vlastnost ThreadState slouží ke zjištění aktuálního stavu vlákna. Na této vlastnosti je zajímavé, že má tři „vrstvy“ různých stavů, rozlišené podle klíče jednu od druhé. Na diagramu jsou uvnitř „bublinek“ jednotlivé hodnoty enumerace a tučně metody, které k jednotlivým hodnotám výčtu vedou. Tři vrstvy, o kterých jsem se zmínil před minutkou, jsou rozdělené takto:

  1. Jestli vlákno běží, je blokováno, nebo je volána metoda Abort
  2. Jestli vlákno běží na pozadí, nebo na popředí (ThreadState.Background)
  3. Podle stavu vlákna vůči metodě Suspend (ThreadState.SuspendRequested a .Suspended)

Ve výsledku se dostáváme k velkému množství hodnot, kterých může vlastnost ThreadState nabývat. Některé z nich vidíte v diagramu nahoře. Vysvětlím, proč je před hodnotou Aborted poznámka „Jen teoreticky!“. Celý výčet možných hodnot totiž obsahuje dvě, které nejsou v současné verzi CLR vůbec implementovány! Jsou jimi Aborted a StopRequested.

Aby se to celé ještě zkomplikovalo, ThreadState.Running má index 0 (indexem teď myslím ten index, který má každá hodnota ve výčtu), takže tento kód by nefungoval:

if ((t.ThreadState & ThreadState.Running) > 0)

Místo toho musíme použít například negaci výše uvedené podmínky, případně vlastnost IsAlive. Ta ale nemusí být vždy to, co chceme, protože ta vrací true, i když je vlákno zablokováno (a false vrací jen před startem vlákna, nebo až po jeho ukončení).

Za předpokladu, že rozumíte metodám Suspend a Resume (to nás čeká později), můžete si napsat pomocnou metodu, která vyřadí všechny hodnoty enumerace, kromě hodnot první vrstvy a díky tomu můžete použít jednoduchý test rovnosti. Zda vlákno běží na pozadí můžeme zjistit nezávisle na druhé vrstvě pomocí vlastnosti IsBackground, takže nakonec jen první vrstva poskytuje hodnoty, které potřebujeme.

public static ThreadState SimpleThreadState (ThreadState ts)
{
    return ts & (ThreadState.Aborted | ThreadState.AbortRequested |
        ThreadState.Stopped | ThreadState.Unstarted |
        ThreadState.WaitSleepJoin);
}

ThreadState je neocenitelný pomocník při debuggingu, přesto je jeho využitelnost pro koordinaci více vláken rozporuplná, protože neexistuje žádný mechanismus, pomocí kterého bychom mohli jednoduše zjistit hodnotu ThreadState a na základě té informace pak jednat, než by se mezitím ta hodnota změnila.

Můžete si oddychnout, možná trochu složitou problematiku vlastnosti ThreadState máme za sebou, stejně jako celý díl. Příště se podíváme na signalizační konstrukce a několik dalších věcí.

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

×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.

3 názory  —  3 nové  
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ý