Vlákno (informatika)
Vlákno (též vlákno řízení, anglicky thread) označuje v informatice spuštěnou instanci počítačového programu. O vláknech mluvíme v souvislosti s možností vytvořit více vláken v jednom procesu, což se nazývá multithreading. Jednotlivá vlákna mohou v rámci procesu vykonávat různé činnosti – například čtení požadavků uživatele, zpracování dat, vykreslování výstupu na obrazovce a síťovou komunikaci – nebo stejnou činnost nad různými daty (např. obsluhu více síťových spojení). U počítačů s více procesory nebo na vícejádrových procesorech mohou tyto činnosti probíhat současně (paralelně), v ostatních případech kvaziparalelně (rychlým přepínáním mezi vlákny se vytváří zdání paralelismu).
Technicky, v systémech a programech, které nepodporují multihreading, má každý proces jen jediné vlákno. Podpora multithreadingu znamená, že je možné v rámci jednoho procesu vytvořit větší počet vláken.
Vlákno můžeme považovat za odlehčený proces – zatímco běžné procesy jsou navzájem striktně odděleny, vlákna jednoho procesu sdílí paměťový prostor a další systémové prostředky. Sdílená paměť zjednodušuje komunikaci mezi vlákny, zvyšuje však riziko souběhu (anglicky race condition). Multithreading snižuje režii operačního systému při přepínání mezi procesy (při změně kontextu), která je nutná pro zajištění multitaskingu - lze jej tak považovat za další stupeň multitaskingu.
Charakteristika
Praktickým rozdílem mezi multithreadovým a multiprocesovým multitaskingem je kromě sdílené paměti (která některé věci usnadňuje a jiné naopak ztěžuje) režie při přepínání:
- Přepnutí mezi vlákny bývá výrazně rychlejší, neboť vlákna sdílejí stejnou paměť a uživatelská práva svého mateřského procesu a není je třeba při přepínání měnit.
- V některých případech není třeba při přepínání vláken volat jádro OS.
- Rychlejší může být i vytváření a rušení vlákna.
- Vlákno také spotřebuje méně paměti, což je důležité pro aplikace, které používají stovky nebo více vláken.
Vlákna je možné vytvořit i čistě na aplikační úrovni bez nativní podpory operačního systému (využitím sdílené paměti a dalších technik). Takto vzniklá vlákna je poté možné spouštět postupně v jednotlivých procesech operačního systému nebo takzvaně m:n, tedy v několika vláknech operačního systému současně spouštět větší počet aplikačních vláken. Toto řešení sice není tak dobré jako řešení s podporou operačního systému – například volání služby operačního systému zablokuje „větší“ vlákno OS a ne jenom aplikační vlákno – ale pro některé úlohy může být stále rychlejší.
Podpora vláken v OS
Z hlediska spravování vláken operačním systému můžeme vlákna rozdělit na:
- vlákna na uživatelské úrovni (ULT)
- vlákna na úrovni jádra (KLT)
- kombinace KLT a ULT
Vlákna na uživatelské úrovni (ULT)
Správu vláken provádí tzv. vláknová knihovna („thread library“) na úrovni aplikačního procesu. Jádro operačního systému o jejich existenci neví a přepínání mezi vlákny nevyžaduje volání funkcí jádra. Nepřepíná se ani kontext procesu ani režim procesoru. Přepínání vláken a jeho plánování je specifické pro konkrétní aplikaci. Programátor má možnost zvolit si nejvhodnější plánovací strategii a příslušný algoritmus. V operačním systému není vyžadováno multiprogramování, stačí speciální knihovna.
Příklad: V případě POSIXu je na uživatelské úrovni k dispozici knihovna POSIX Threads (též Pthreads).
Vláknová knihovna
Pro provozování vláken na uživatelské úrovni je třeba speciální knihovna, která musí umožňovat:
- rušení a vytváření vláken
- předávání dat a zpráv mezi vlákny
- plánování běhu vláken
- uchovávání a obnova kontextu vláken
Výhody uživatelských vláken
- nezávislost na podpoře vláken v operačním systému
- přepínání mezi vlákny je nezávislé na operačním systému (může být i rychlejší)
- výrazně rychlejší tvorba a přepínání vláken
- plná kontrola procesu nad správou běhu vláken
Nevýhody
- volání služby jedním vláknem zablokuje všechna vlákna procesu
- nutnost dodatečného programování (řízení vláken programátorem)
- pokud jádro přiděluje procesor pouze procesům, nemohou dvě vlákna téhož procesu běžet současně, i když systém obsahuje více procesorů
Vlákna na úrovni jádra OS (KLT)
Veškerá správa vláken je řízena operačním systému a každé vlákno v uživatelském prostoru je zobrazeno na vlákno v jádře. Jádro samo vlákna vytváří, ruší a plánuje.
Výhody
- volání systému neblokuje ostatní vlákna téhož procesu
- jeden proces může využít více procesorů
- tvorba, rušení a přepínání mezi vlákny je levnější než mezi procesy
- i programy jádra mohou mít vícevláknový charakter
Nevýhody
- správa je nákladnější než u čistě uživatelských vláken
Příklady
- Windows NT 4.0/2000/XP
- Linux
- 4.4BSD UNIX
Kombinace ULT a KLT
Některé operační systémy podporují oba způsoby běhu vláken. Přiřazování uživatelských vláken k systémovým se děje automaticky (bez programátora) anebo programátor může nastavit počet vláken na úrovni jádra.
Podpora u OS
Kombinaci ULT a KLT podporují například následující OS:
- Windows 2000/XP s nadstavbou ThreadFiber
- FreeBSD 5.x
Kdy se vlákna používají
- Obsluha periferií
- U některých zařízení je třeba periodicky testovat stav hardware.
- Vláknu pak nemusí zbývat mnoho času na obsluhu uživatelského rozhraní.
- Jedno vlákno pro komunikaci s uživatelem a druhé obsluhuje hardware
- Síťová komunikace
- Jedno vlákno akceptuje příchozí komunikace.
- Jedno vlákno odesílá data.
- Jedno vlákno zpracovává data.
- Vyvolání dojmu rychlé odezvy programu
- Práce s velkým objemem data uložených v databázi.
- Hlavní vlákno pouze obsluhuje uživatelské rozhraní, další pracuje s databází.
- Urychlení výpočtu
- Lze-li spustit na víceprocesorovém stroji kooperující vlákna na několika procesorech.
- Vhodné pro architekturu aplikace
- Simulace – jedno vlákno počítá vlastní simulaci.
- Další vlákno periodicky vzorkuje stav simulace a zobrazuje ho.
- Primární vlákno obsluhuje uživatelské rozhraní
- Efektivita
- Některé aplikace jsou ze své podstaty nevhodná pro jednovláknovou architekturu.
- Použití vláken může vést k výraznému zpřehlednění programového kódu
- V moderním OS už beztak běží několik vláken, pár navíc nehraje roli. Každý operační systém má maximální strop na počet threadů, kdy je plánování procesu stále ještě efektivní.
Vlákna je výhodné použít, pokud aplikace splňuje některé následující kritérium
- Je složena z nezávislých úloh.
- Může být blokována po dlouho dobu.
- Obsahuje výpočetně náročnou část.
- Musí reagovat na asynchronní události.
- Obsahuje úlohy s nižší nebo vyšší prioritou než zbytek aplikace.
Výhody vláken obecně
- Odezva: vlákna mohou umožnit aplikaci zachování dobré odezvy na uživatelský vstup. V programu s jedním vláknem se může stát, že hlavní vykonávaná činnost programu blokuje úlohu, která potřebuje dlouhou dobu na zpracování, může se zdát, že je celý program zamrzlý. Tím, že se pro dlouhotrvající úlohu vytvoří pracovní vlákno, které poběží současně s hlavním vláknem programu, je možné zachovat rychlou odezvu prostředí programu a přitom provádět delší operace na pozadí. Na druhou stranu většinou nemusí být více vláken jediným řešením, jak udržet kvalitu odezvy programu. Z dalších řešení se jedná např. o asynchronní vstup/výstup (I/O) nebo specifické unixové signály.
- Rychlejší běh programu: tato výhoda využití více vláken v programech umožňuje rychlejší průběh na počítačích s více CPU nebo s CPU o více jádrech (nebo i počítačovém clusteru). Je tomu tak díky kapacitě vícejaderných procesorů vlákna (i procesy) vykonávat skutečně souběžně.
- Nižší spotřeba výkonu: s využitím vláken může aplikace spravovat více klientů souběžně při nižší spotřebě výkonu než by bylo nutné při opakovaném (duplicitním) spuštění téhož programu pro každého z klientů.
- Lepší využití systému: typický příklad lze demonstrovat na práci se systémem souborů. Při využití vláken lze dosáhnout vyššího datového toku a nižší odezvy přičemž data z rychlé paměti (např. paměť typu cache) mohou být získány jedním vláknem zatímco jiné vlákno získává data z pomalejšího typu paměti (např. externího disku apod.) aniž by na sebe vlákna musela vzájemně čekat.
- Zjednodušené sdílení a komunikace: na rozdíl od procesů, které vyžadují předávání zpráv procesům nebo možnosti sdílení paměti k využití meziprocesové komunikace (IPC), mohou vlákna komunikovat skrz data, kód či soubory, které sdílí.
- Paralelní běh: aplikace, které chtějí využít výhody procesorů s více jádry nebo systémy s více procesory mohou využít vlákna k rozdělení dat a úloh do paralelních podřízených úloh, které poté budou zpracovány souběžně na více jádrech (procesorech) daného systému. Výpočetní prostředí jako jsou CUDA nebo OpenCL na GPU využívají vláken díky velkému množství jader GPU, na kterých běží souběžně stovky úloh.
Nevýhody vláken
- Vlákna by se měla používat jen tam, kde je to opravdu nutné, protože tvorba vlákna na určitých platformách je poněkud zdlouhavá operace.
- K vyřešení tohoto problému se u vícevláknových aplikací používá mechanismus sdružování vláken.
- Každé vytvořené vlákno vytváří v paměti vlastní zásobník, do kterých jsou ukládány mezivýsledky, stavy proměnných, adresy apod.
- I když je teoreticky možné vytvářet obrovský počet vláken, maximální počet vláken je omezen platformou.
- Zvýšená složitost kódu.
- Daleko složitější sledovat tok programu.
- Sdílení prostředků, za kterou je většinou odpovědný programátor.
- K řízení sdílení prostředků se používá synchronizace → zaručuje, že stav dat nebude změněn z více vláken zároveň.
Modely vícevláknových aplikací
Modely řeší způsob vytváření a rozdělování práce mezi vlákna.
- Boss/Worker – hlavní vlákno řídí rozdělení úlohy jiným vláknům.
- Peer – vlákna běží paralelně bez specifického vedoucího.
- Pipeline – zpracování dat sekvencí operací. Předpokládá dlouhý vstupní proud dat.
Boss/Worker
Hlavní vlákno je zodpovědné za vyřizování požadavků. Pracuje v cyklu:
- příchod požadavku,
- vytvoření vlákna pro řešení příslušného úkolu,
- návrat na čekání požadavku.
Výstup řešení úkolu je řízen
- Příslušným vláknem řešícím úkol.
- Hlavním vláknem, předání využívá synchronizační mechanismy.
Peer model
- Neobsahuje hlavní vlákno.
- První vlákno po vytvoření ostatních vláken:
- se stává jedním z ostatních vláken (rovnocenným),
- pozastavuje svou činnost do doby než ostatní vlákna končí.
- Každé vlákno je zodpovědné za svůj vstup a výstup.
Pipeline
- Dlouhý vstupní proud dat.
- Sekvence operací (částí zpracování), každá vstupní jednotka musí projít všemi částmi zpracování.
- V každé části jsou v daném čase, zpracovány různé jednotky vstupu (nezávislost jednotek).
Vícevláknové aplikace a ladění
Hlavní problémy vícevláknových aplikací souvisí se synchronizací:
- uváznutí (deadlock) – dvě nebo více vláken se trvale vzájemně blokují tím, že každé vlákno čeká na prostředek, který je přidělen jinému vláknu
- souběh (race conditions) – přístup více vláken ke sdíleným proměnným a alespoň jedno vlákno nevyužívá synchronizačních mechanismů. Vlákno čte hodnotu zatímco jiné vlákno zapisuje. Zápis a čtení nejsou atomické a data mohou být neplatná.
- vyhladovění (starvation) – stav, kdy jsou vláknu neustále odepírány prostředky. Bez těchto prostředků program nikdy nedokončí svůj úkol.
Příklady aplikací
- Servery: obsluhují více klientů najednou. Obsluha typicky znamená přístup k několika sdíleným zdrojům a hodně vstupně výstupních operací (I/O).
- Výpočetní aplikace: na víceprocesorovém systému lze výpočet urychlit rozdělením úloh na více procesorů.
- Aplikace reálného času: lze využít specifických plánovačů. Vícevláknová aplikace je výkonnější než složité asynchronní programování, protože vlákno čeká na příslušnou událost namísto přerušování vykonávání kódu a přepínání kontextu.
Příklady přepínání kontextu
- Nepreemptivní multitasking: K tomu, aby mohl procesor vykonávat více operací musí přesouval pozornost od jednoho vlákna k druhému, tomuto procesu se říká přepínání kontextu. Ke kontextovému přepnutí může dojít, když se vlákno dobrovolně vzdá svého času procesoru, který tento čas může přidělit jiným vláknům. Tomuto systému se též říká „kooperativní multitasking“. Může ovšem dojít k tomu, že se programátor omylem nebo záměrně nevzdá času vlákna ve prospěch procesoru nebo jiného vlákna, což způsobí zatuhnutí aplikace a zablokuje běh všech dalších vláken. Tento systém přepínání kontextu se používal u starších operačních systémů (například řada systémů Windows pro DOS) a umožňoval vytuhnutí aplikace nebo dokonce celého operačního systému vinou jednoho vlákna.
- Preemptivní multitasking: Podstatně lepším řešením je preemptivní multitasking, kde plánovací modul OS rozhoduje kdy přerušit či pozastavit běh vlákna a spustit vlákno jiné, aniž by narušil běh úlohy. Tento druh multitaskingu zabraňuje vláknu monopolizovat čas procesoru a nevyžaduje, aby programátor rozhodoval, kdy se vzdát času procesoru. Toto má jako vždy svou nevýhodu, protože programátor musí zajistit správnou koordinaci využívání prostředků.
Podpora ze strany programovacích jazyků
IBM PL/1(F) zahrnoval podporu více vláken na konci 60. let a podpora pokračovala i v pozdějších verzích jazyka. Compiler tohoto jazyka také představil nové API pro vlákna.
Mnoho jiných programovacích jazyků do určité míry podporuje vlákna. Mnoho implementací jazyků C a C++ zajišťuje podporu vláken samostatně, ale také zahrnují i přístup k nativnímu API vláken zajištěného operačním systémem.
Některé programovací jazyky vyšší úrovně (často multiplatformní) jako jsou Java, Python či .NET umožňují řešení vláken vývojáři aplikace a abstrahují specifika vláken podle dostupného systému za běhu programu.
Množství dalších programovacích jazyků ponechává paralelní běh a vlákna kompletně na programátorovi (Cilk, OpenMP, MPI).
Některé programovací jazyky jsou vyloženě zaměřené na paralelní běh programů (Ateji PX, CUDA).
Související články
Externí odkazy
- Obrázky, zvuky či videa k tématu Vlákno na Wikimedia Commons
- El. forma přednášek z Technické univerzity v Liberci – autor: Ing. Igor Kopetschke