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

 
Hledat
Vybavení pro Laser Game
Spuštěn Filmový magazín
Laser Game Brno
Pergoly a střechy Brno

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

Google       Google       26. 8. 2008       26 775×

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

Reklama
Reklama

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

Reklama
Reklama
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í.

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

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