Zarábaj až 6 000 € mesačne! Akreditované rekvalifikačné kurzy od 0 €. Viac informácií.

1. diel - Úvod do viacvláknových aplikácií v C # .NET

Vitajte u prvej lekcie kurzu o programovaní viacvláknových aplikácií čiže multithreadingu v C# .NET. Naučíme sa tu plne využívať moderné viacjadrové procesory a tiež spúšťať na pozadí úlohy, ktoré by inak zasekli hlavné vlákno aplikácie. Dostaneme sa aj k najnovším technológiám z .NET frameworku ako sú paralelné programovanie, úlohy alebo kľúčové slová async a await.

Úvod do teórie vlákien

Než začneme používať vlákna, popíšme si akým spôsobom spúšťa aplikácie náš operačný systém. Keďže sme u C #, tak môžeme hovoriť o Windows, avšak princíp platí pre väčšinu ostatných. Windows je viacúlohový operačný systém (multitasking). To znamená, že dokáže spustiť viac aplikácií naraz. Pritom jadro procesora dokáže zvyčajne spustiť len jednu inštrukciu v jeden čas. Iste viete, že Windows dokázal spúšťať viacero aplikácií naraz dlho predtým, než boli na trhu viacjadrové procesory a aj teraz si môžete spustiť koľko aplikácií chcete a to bez ohľadu na to, kolikajádrový procesor vlastníte. Ako je to možné?

Windows medzi spustenými aplikáciami jednoducho rýchlo prepína (presnejšie to robí tzv. Scheduler ao prepínanie hovoríme ako o timeslicingu). Systém jednu aplikáciu zastaví a spustí na okamih aplikáciu inú. Užívateľ to vníma ako by aplikácia bežali naraz, aj keď to tak v skutočnosti nie je. S príchodom viacjadrových procesorov sa princíp nezmenil, Windows stále prepína medzi aplikáciami, avšak dokáže vykonávať niekoľko inštrukcií naraz na každom procesorové jadrá.

Aplikácie, proces a vlákno

Zamyslime sa nad termíny aplikácie, proces a vlákno. Aplikáciu si iste dokážeme predstaviť, je to napr. Internetový prehliadač, v ktorom čítate tento článok. Čo je však proces a čo vlákno?

Proces

Proces je inštancia bežiace aplikácie. Pokiaľ si spustíme 3x kalkulačku, nájdeme v správcovi úloh 3x proces calc.exe. Niektoré zložitejšie aplikácie môžu využívať niekoľko procesov, napr. Google Chrome vytvorí proces pre každú otvorenú záložku. Väčšinou majú aplikácie však len jeden proces.

Správca úloh Windows - Paralelné programovanie a viacvláknové aplikácie v C # .NET

Vlákno

V procese môže bežať niekoľko jeho vlákien. Každá aplikácia má minimálne jeden proces, v ktorom beží jej hlavné vlákno, prípadne nejaká ďalšie vlákna. Zatiaľ, čo hlavný vlákno máme pripravené, ďalšie vlákna si vytvárame my sami. Operačný systém spustí naše vlákno na nejakom jadre a potom ho rýchlo uspáva a prebúdza ako sa mu to zrovna hodí. Vo výsledku nám vlákna v procese beží paralelne a môžeme napr. Vykonávať nejaké zložité analýzy, bez toho aby sme zasekli hlavné vlákno aplikácie a to dokonca aj v niekoľkých vláknach naraz, pričom bude samotný výpočet niekoľkokrát rýchlejšie.

Synchronizácia

Všetko znie skvele, že? Vlákna sa však v praxi používajú naozaj len pokiaľ je nutne potrebujeme. Je s nimi totiž spojený jeden obrovský problém a tým je synchronizácia. Nikdy nevieme, kedy budú naše vlákna uspanie, systém to vykoná bez ohľadu na to, čo dané vlákno práve robí. Asi si dokážeme predstaviť, že sa metóda vlákna zasekne na nejakom riadku zdrojového kódu. V skutočnosti sa však môže zaseknúť aj napr. V polovici sčítanie, pretože na 32-bitovom procesore sú ku sčítanie 64bitových čísel potrebné 2 inštrukcie. Ak túto hodnotu používame iným vláknom, môže v nej byť nezmysel. Ukazovatele sa tiež v jadrách cachují, takže sa môže stať, že má v rovnaký čas rovnaká premenná niekoľko rôznych hodnôt. K problémom synchronizácia sa dostaneme počas seriálu pomerne podrobne a naučíme sa je tiež riešiť.

Vlákna určite nie sú niečo, čo by každá aplikácia musela nutne obsahovať a hoci sa inžinieri z Microsoftu snaží čo môžu, aby prácu s nimi čo najviac zjednodušili (a že sa im to darí), stále technológia vo výsledku aplikácii skomplikuje. Určite je používajte s rozvahou.

Prvý viacvláknové aplikácie

Naprogramujeme si prvé viacvláknové aplikácie. Pre zjednodušenie budeme nejakú dobu pracovať iba v konzole. Založte si nový projekt, ktorý pomenujte Prepinac. K projektu pridáme rovnomennou triedu s nasledujúcim obsahom:

class Prepinac
{

    public void Vypisuj0()
    {
        while (true)
        {
            Console.Write("0");
        }
    }

    public void Vypisuj1()
    {
        while (true)
        {
            Console.Write("1");
        }
    }

    public void Prepinej()
    {
        Thread vlakno = new Thread(Vypisuj0);
        vlakno.Start();
        Vypisuj1();
    }

}

Prvé 2 metódy triedy sú veľmi jednoduché a simulujú nejakú dlhšiu činnosť. Prvá metóda do nekonečna vypisuje nuly do konzoly, druhá metóda rovnakým spôsobom vypisuje jedničky.

Metóda Prepinej() je pre nás už zaujímavejšie. Sama spustí výpis jedničiek, ale ešte predtým vytvorí nové vlákno, ktorému priradí metódu pre výpis núl. Toto vlákno potom tiež spustí.

Vlákna sú v .NET reprezentované triedou Thread. V konstruktoru ju odovzdáme delegát ThreadStart, ktorý má túto podobu:

public delegate void ThreadStart();

Vláknu teda môžeme odovzdať bezparametrickou metódu typu void. V metóde main() vytvoríme inštanciu prepínače a necháme ho prepínať:

static void Main(string[] args)
{
    Prepinac prepinac = new Prepinac();
    prepinac.Prepinej();
}

Keď aplikáciu spustíme, získame takýto výstup:

Prepínanie vlákien v C# .NET - Paralelné programovanie a viacvláknové aplikácie v C # .NET

Všimnite si, že jednotky a nuly nie sú úplne na striedačku, ako by sme mohli očakávať. Je vidieť, ako vlákno chvíľu beží a potom ich uspanie. Intervaly sa tiež líšia, aj keď priemerne beží obe vlákna rovnako dlho.

Vlastnosti triedy Thread

Zatiaľ pre nás budú dôležité len tieto vlastnosti na triede Thread:

  • IsAlive - Označuje, či metóda vlákna beží.
  • Name - Každé vlákno si môžeme pomenovať, čo nám uľahčí ladenie aplikácie.

Hlavné vlákno aplikácie

K hlavnému vláknu aplikácie sa dostaneme pomocou statické vlastnosti Thread.Curren­tThread. Bohužiaľ nemá v predvolenom stave priradené žiadne meno, skúsme mu ho priradiť a vypísať.

static void Main(string[] args)
{
    Thread.CurrentThread.Name = "Hlavní vlákno";
    Console.WriteLine(Thread.CurrentThread.Name);
}

V budúcej lekcii, Vlákna - Príklady viacvláknových aplikácií v C# .NET , sa pozrieme na uspávanie vlákien, ich spájanie a základy synchronizácie.

V budúcej lekcii, Vlákna - Príklady viacvláknových aplikácií v C# .NET , si vyskúšame naprogramovať dve viacvláknové aplikácie, v ktorých sa naučíme vlákna zakladať, pomenovať a spúšťať.


 

Všetky články v sekcii
Paralelné programovanie a viacvláknové aplikácie v C # .NET
Preskočiť článok
(neodporúčame)
Vlákna - Príklady viacvláknových aplikácií v C# .NET
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity