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
Laser Game Ostrava

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

Google       Google       26. 8. 2008       25 160×

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 Využití .htaccess na malém webu

Využití .htaccess na malém webu

V dnešní době existuje spoustu cms, které mnohdy ale vůbec nepotřebujeme a stačila by nám pouze základní funkčnost k úpravě url, přesměrování. K tomuto účelu je ideální .htaccess soubor, který nám se všemi těmato úpravami umí pomoct.

Reklama
Reklama
Obrázek ke článku Češi tlačí obce do otevřené komunikace – Mobilní Rozhlas si loni pořídilo dalších 171 měst a obcí

Češi tlačí obce do otevřené komunikace – Mobilní Rozhlas si loni pořídilo dalších 171 měst a obcí

Obyvatelé Česka se mnohem více zapojují do veřejného dění. Umožňují jim to přímo samosprávy, které stále častěji využívají nástroje takzvané chytré komunikace a participace. Dokládají to data za rok 2019 ekosystému Mobilní Rozhlas, lídra v oblasti chytré obecní komunikace. Zapojilo se do něj 171 nových měst a obcí, zaregistrovalo celkem 100 tisíc občanů a místní samosprávy jeho prostřednictvím rozeslaly třikrát více adresných zpráv než v roce 2018

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