NOVINKA - Online rekvalifikační kurz Python programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 3 - Vlákna - Uspání, blokování a stavy vláken ve VB.NET

V minulé lekci, Vlákna - Příklady vícevláknových aplikací ve VB.NET, jsme si naprogramovali dvě vícevláknové aplikace, ve kterých jsme se naučili vlákna zakládat, pojmenovat a spouštět.

V dnešním VB.NET tutoriálu se naučíme základy synchronizace vláken. Ukážeme si, jak vlákna uspat a blokovat. Představíme si třídu Thread a seznámíme se se stavy vláken. Vše si ukážeme na funkčních příkladech.

Uspaní vláken

V rámci práce s vícevláknovým prostředím nabízí třída Thread užitečné metody pro řízení toku vláken, mezi nimiž patří metoda Sleep(). Metoda Sleep() na třídě Thread se používá pro dočasné pozastavení běhu aktuálního vlákna na definovanou dobu v milisekundách. Typickým použitím je simulace čekání na určitou událost, nebo zpomalení běhu programu.

Pro zápis doby uspání můžeme v parametru metody Sleep() využít strukturu TimeSpan.

Metoda Sleep()

Uspání vlákna na dobu 1 hodiny provedeme takto:

Thread.Sleep(3600000)

Metoda Sleep() s TimeSpan

S využitím struktury TimeSpan uspíme vlákno na stejnou dobu takto:

Thread.Sleep(TimeSpan.FromHours(1))

Blokování vláken

Další užitečnou metodou třídy Thread je metoda Join(). Metoda Join() blokuje volající vlákno, dokud se vlákno reprezentované instancí typu Thread neukončí. Metoda umožňuje synchronizaci vláken a čekání na dokončení určitého vlákna před pokračováním ve zpracování hlavního vlákna. To je užitečné v situacích, kdy potřebujeme vyčkat na dokončení nějaké operace.

Příklad

Nejlépe to uvidíme na příkladu. Založme si novou konzolovou aplikaci. Budeme pracovat pouze v Module1.vb.

Proměnná hodnota

Nejdříve si nad metodu Main() vložme proměnou hodnota, kterou naplňme hodnotou 0:

Dim hodnota As Integer = 0

Metoda PrictiJedna()

Pod metodu Main() si napišme první metodu, kterou budeme volat, metodu PrictiJedna(). V metodě implementujeme zvýšení hodnoty proměnné hodnota o hodnotu 1 a její výpis do konzole:

Sub PrictiJedna()
    For i As Integer = 1 To 10
        hodnota += 1
    Next

    Console.WriteLine("Hodnota proměnné: {0}", hodnota)
End Sub

Metoda OdectiJedna()

Podobně implementujeme metodu OdectiJedna(). V metodě tedy snížíme hodnotu proměnné hodnota o 1 a vypíšeme ji do konzole:

Sub OdectiJedna()
    For i As Integer = 1 To 10
        hodnota -= 1
    Next

    Console.WriteLine("Hodnota proměnné: {0}", hodnota)
End Sub

Metoda Main()

Pomocné metody implementované máme. Můžeme se tedy vrhnout na dokončení programu v metodě Main():

Imports System.Threading

Module Module1
    Dim hodnota As Integer = 0

    Sub Main()
        Dim pricteniThread As New Thread(AddressOf PrictiJedna)
        Dim odecitaniThread As New Thread(AddressOf OdectiJedna)

        pricteniThread.Start()
        pricteniThread.Join()

        odecitaniThread.Start()
        odecitaniThread.Join()

        Console.WriteLine("Výsledek: {0}", hodnota)

        Console.ReadKey()
    End Sub
End Module

Vytvoříme dvě vlákna. Vlákno:

  • pricteniThread, v jehož konstruktoru zavoláme metodu PrictiJedna(),
  • odecitaniThread, v jehož konstruktoru zavoláme metodu OdectiJedna().

Obě vlákna spustíme a poté na nich zavoláme metodu Join(). Nakonec do konzole vytiskneme výslednou hodnotu proměnné hodnota.

Testování

Po spuštění aplikace vidíme, jak se hodnota proměnné hodnota mění:

Konzolová aplikace
Hodnota proměnné: 10
Hodnota proměnné: 0
Výsledek: 0

Stavy vláken

Podívejme se na některé ze stavů, které vlákno může nabývat. Stav vlákna lze zjistit pomocí jeho vlastnosti ThreadState, která je výčtovým typem sestávajícím z jedné nebo více z následujících hodnot:

  • Running – Vlákno je v běhu, provádí svůj kód.
  • StopRequested – Bylo požádáno o zastavení vlákna, ale ještě nebylo zastaveno.
  • SuspendRequested – Bylo požádáno o pozastavení vlákna, ale ještě nebylo pozastaveno.
  • Background – Vlákno je nastaveno jako pozadí.
  • Unstarted – Vlákno bylo vytvořeno, ale ještě nebylo spuštěno.
  • Stopped – Vlákno bylo zastaveno.
  • WaitSleepJoin – Vlákno čeká v režimu spánku nebo na spojení.
  • Suspended – Vlákno bylo pozastaveno.
  • AbortRequested – Bylo požádáno o zrušení vlákna, ale ještě nebylo zrušeno.
  • Aborted – Vlákno bylo zrušeno.

Příklad

Ukažme si výpis stavů vláken na příkladu.

Metoda Counting()

V konzolové aplikaci si napíšeme tuto metodu:

Sub Counting()
    For i As Integer = 0 To 4
        Console.WriteLine(i)
        Thread.Sleep(500)
    Next
End Sub

V metodě Counting() provádíme číslování od 0 do 4 s výpisem čísel. Mezi každý výpis vkládáme pauzu trvající 500 milisekund.

Metoda Main()

Do metody Main() přidáme následující kód:

Imports System.Threading

Module Module1
    Sub Main()
        Dim countingThread As New Thread(AddressOf Counting)
        Console.WriteLine("Stav vlákna po vytvoření: {0}", countingThread.ThreadState)

        countingThread.Start()
        Console.WriteLine("Stav vlákna po spuštění: {0}", countingThread.ThreadState)

        Thread.Sleep(100)
        Console.WriteLine("Stav vlákna po chvilce čekání: {0}", countingThread.ThreadState)

        countingThread.Join()
        Console.WriteLine("Stav vlákna po dokončení: {0}", countingThread.ThreadState)

        Console.ReadKey()
    End Sub
End Module

V metodě Main() vytváříme nové vlákno pomocí třídy Thread a jejího konstruktoru, kterému předáváme metodu Counting(). Poté vypisujeme stav vlákna pomocí vlastnosti ThreadState v různých bodech životního cyklu vlákna.

Stav vlákna je zajímavý pouze ve scénářích ladění. Kód by nikdy neměl používat stav vlákna k synchronizaci aktivit vláken.

Testování

Spuštěním kódu uvidíme výpis stavů vláken:

Konzolová aplikace
Stav vlákna po vytvoření: Unstarted
Stav vlákna po spuštění: Running
0
Stav vlákna po chvilce čekání: WaitSleepJoin
1
2
3
4
Stav vlákna po dokončení: Stopped

V příští lekci, Vlákna - Bezpečnost vláken ve VB.NET, se budeme zabývat bezpečností vláken ve VB.NET. Vybereme si jednu techniku sdílení dat mezi vlákny, kterou implementujeme do příkladu.


 

Předchozí článek
Vlákna - Příklady vícevláknových aplikací ve VB.NET
Všechny články v sekci
Paralelní programování a vícevláknové aplikace v VB.NET
Přeskočit článek
(nedoporučujeme)
Vlákna - Bezpečnost vláken ve VB.NET
Článek pro vás napsal Ondřej Štorc
Avatar
Uživatelské hodnocení:
4 hlasů
Autor se věnuje C#, HTML a CSS. Snaží se proniknout do tajů PHP, JS a ASP.NET
Aktivity