Vícevláknové programování
DVOP PIT
Bc. Matěj Cajthaml — SSPŠ
©
Processory
- jednojádrové
- CPU má pouze jeden výpočetní prvek
- zpracovává jeden instrukční tok
- vícerojádrové
- CPU má více výpočetních prvků
- každé jádro má zpracovává alespoň jeden instrukční tok
- hypertreading
- multithreading
Přerušení
- přerušení je událost, která vyvolává přerušení běžícího programu
- přerušení může být vyvoláno
- vnější událostí
- instrukcí
- chybou
- přerušení přestane zpracovávat aktuální instrukční tok a přejde na obsluhu
přerušení
- po obsloužení přerušení se vrátí k původnímu instrukčnímu toku
Program
- spustitelný binární program
- soubor instrukcí pro CPU
- data proměnných, informace o knihovnách, ...
Process
- instance spuštěného programu
- obsahuje všechny informace o běžícím programu
- alokováné prostředky
Vlákno
- thread
- jednotka zpracování (proud instrukcí)
- přiděleno jádru procesoru
- sdílí nějaké prostředky s ostatními vlákny z procesu
Informace o vláknech
- ID
- zásobník: lokální proměnné, návratová adresa, ...
- přepínání vláken: čítač instrukcí, registry, ...
- plánování: priorita, stav, ...
Vytvoření vlákna
- různé způsoby dle OS a programovacího jazyka
- většinou je potřeba předat funkci, která se má vykonávat
- dva módy:
- fork: vytvoří kopii procesu
- thread: vytvoří nové vlákno v rámci procesu
Ukončení procesu
- sám sebe: ukončí se sám ukončením v hlavním vlákně
- jádrem: ukončí se příkazem z jádra, např. chyba
Víme co jsou to vlákna. Proč je velký problém komunikace mezi nimi?
Thread
- třída, která reprezentuje vlákno
- obsahuje metody pro práci s vlákny
- při zapnutí určujeme funkci, která se má vykonávat
System.Threading
Ukázka 1
Co a kdy se vypíše?
Ukázka 2
Co a kdy se vypíše?
Připojení k vláknu
- čekání na dokončení vlákna
.Join()
Čekání ve vlákně
- čekání na nějakou událost, data, ...
.Sleep()
Ukázka 3
Co a kdy se vypíše?
Přepínání vláken
- kontext = aktuální stav vlákna
- proces:
- uloží se kontext vlákna
- naplánuje se jiné vlákno
- obnoví se kontext jiného vlákna
Stavy vláken
- idle: čeká na přidělení procesoru
- ready: připraveno k běhu, čeká na přiřazení jádra
- running: běží
- blocked: čeká na nějakou událost
- zombie: ukončené vlákno, čeká na uvolnění zdrojů
- free: uvolněné vlákno
Stavy vláken
graph LR
A(idle) --> B(ready)
B --> C(running)
C --> B
C --> D(blocked)
D --> B
C --> E(zombie)
E --> F(free)
Chyby (bez) synchronizace
- operace nejsou atomické
- vlákna se přepínají, běží paralelně
- vlákna si mohou přepsat data nebo pracovat s neplatnými daty
Kritická sekce
- část kódu, která pracuje s daty
- více vláken nemůže být v kritické sekci současně
- vlákna se musí synchronizovat
- více způsobů
Zámky
- mutex
- při vstupu do kritické sekce se zamkne (atomicky)
- při výstupu se odemkne (atomicky)
- pokud vlákno zjistí při zamykání, že je zamčeno, čeká až bude odemčeno
ReleaseMutex
a WaitOne
V minulé ukázce byl problém. Který?
C# podporuje lock
pro zamykání. Jaký je rozdíl mezi nim a mutexem?
Další synchronizační prostředky
Práce
Zjistěte si informace o semafórech, monitor a bariérách.
Časově závislé chyby
- vlákna zapisují do sdílených dat
- vlákna se přepínají
- chyba závislá na čase
Uváznutí (deadlock)
- vlákna čekají na událost
- událost může zavolat jen čekající vlákno
Živé uváznutí (livelock)
- vlákna zpracovávají program
- vlákna ale nemohou dokončit program
Hladovění (starvation)
- vlákna čekají na událost
- událost ale trvá dlouho
- vlákna nemohou pokračovat
Řešení uváznutí
- zamykání vždy ve stejném pořadí
- pečlivě navržené zamykání
Plánování vláken
- záležitost OS
- obyčejné přepínání
- přepínání na základě časovače, priority, dynamické priority, ...
- kooperativní plánování
Toto řešení není ideální. Proč?
Producent a konzument
- něco přidává do fronty
- něco odebírá z fronty (zpracovává)
- (a obdoby)
Co když bude konzumentů více?
Úlohy
- paralelní řazení pole
- zpracovávání bankovních transakcí
- tisková fronta
- ...
Thread pool
Práce
Zjistěte, k čemu slouží thread pool a jak jej vytvořit.
Děkuji za pozornost!
- matej.cajthaml@ssps.cz
- https://ssps.cajthaml.eu/