Taképrogramové vlákno, vlákno procesu, execution threadPokročilý
Definice
Vlákno je samostatná posloupnost vykonávání instrukcí uvnitř procesu, kterou operační systém nebo běhové prostředí plánuje na procesor. Více vláken může sdílet paměť a otevřené zdroje stejného procesu, takže usnadňují souběžnou práci, ale vyžadují synchronizaci kvůli závodům, deadlockům a obtížně reprodukovatelným chybám.
Nezaměňujte: Vlákno může znamenat jednotku souběžného běhu v programu, diskusní konverzaci nebo hardwarové vlákno procesoru; zde jde hlavně o programové vlákno.
Co vlákno sdílí s procesem
Vlákno patří do procesu. Proces drží adresní prostor, otevřené soubory, síťová spojení a další prostředky. Jednotlivá vlákna ve stejném procesu typicky sdílejí haldu a globální data, ale každé vlákno má vlastní zásobník, sadu registrů a místo v programu, kde právě pokračuje.
Plánovač operačního systému rozhoduje, kdy které vlákno dostane čas na procesoru. Na jednom jádře se vlákna střídají tak rychle, že program působí souběžně. Na více jádrech mohou některá vlákna běžet skutečně paralelně. Běhové prostředí jazyka k tomu může přidávat vlastní pravidla, například správu vláken v JVM, .NET runtime nebo omezení GIL v CPythonu.
Proč sdílená paměť komplikuje kód
Sdílená paměť je hlavní důvod, proč jsou vlákna rychlá i nebezpečná. Přístup k jedné proměnné z více vláken může skončit závodem: výsledek závisí na pořadí kroků, které programátor přímo neřídí. Typickým řešením je zámek, mutex, semafor, atomická operace, fronta zpráv nebo neměnná datová struktura.
Synchronizace zároveň něco stojí. Špatně zvolený zámek může zmenšit paralelismus, zavést čekání nebo způsobit deadlock, kdy dvě vlákna navzájem drží prostředky, které potřebuje druhé. Testování takových chyb bývá obtížné, protože problém často zmizí po přidání logování nebo při spuštění na jiném stroji.
Dva praktické scénáře s vláknem
Server zapisuje auditní log mimo hlavní požadavek
Webová aplikace přijme objednávku a potřebuje rychle odpovědět zákazníkovi. Zápis auditního záznamu do pomalejšího úložiště může běžet ve worker vlákně, aby hlavní obsluha požadavku nečekala na disk nebo síť. Výsledek je kratší latence odpovědi, ale aplikace musí ošetřit pád workeru a zaplnění fronty.
import threading
def uloz_audit(objednavka_id):
print(f"ukládám audit pro {objednavka_id}")
threading.Thread(target=uloz_audit, args=(42,), daemon=True).start()Mobilní aplikace přesune výpočet mimo UI thread
Mobilní aplikace načítá a zmenšuje velkou fotografii. Výpočet v hlavním UI vlákně by zablokoval kreslení obrazovky a uživatel by viděl zaseknuté rozhraní. Worker vlákno připraví náhled na pozadí a hotový výsledek předá zpět mechanismem, který smí bezpečně měnit uživatelské rozhraní.
Kde se vlákno liší podle prostředí
Vlákno nemusí vždy znamenat totéž na všech úrovních. Nativní vlákno je objekt operačního systému. Vlákno v jazyce může být mapované na nativní vlákno, nebo může jít o lehčí abstrakci spravovanou runtime. Korutina obvykle není totéž co vlákno, protože se přepíná spolupracujícím způsobem a často běží nad menším počtem skutečných vláken.
Hardwarové vlákno je další význam: procesor s technikou simultánního multithreadingu nabízí více logických běhových kontextů na jednom fyzickém jádře. Programátor aplikací však obvykle řeší hlavně programová vlákna, jejich synchronizaci a dopad na odezvu nebo propustnost systému.
Příklady z praxe
Auditní log mimo hlavní požadavek
Webová aplikace přijme objednávku a nechce zdržovat zákazníka zápisem auditního záznamu do pomalejšího úložiště. Worker vlákno provede zápis na pozadí, hlavní obsluha požadavku vrátí odpověď dříve. Aplikace ale musí ošetřit pád workeru a zaplnění fronty úloh.
import threading def uloz_audit(objednavka_id): print(f"ukládám audit pro {objednavka_id}") threading.Thread(target=uloz_audit, args=(42,), daemon=True).start()Výpočet mimo UI thread
Mobilní aplikace načítá a zmenšuje velkou fotografii. Výpočet v hlavním UI vlákně by zablokoval kreslení obrazovky a uživatel by viděl zaseknuté rozhraní. Worker vlákno připraví náhled na pozadí a hotový výsledek předá zpět bezpečným mechanismem pro úpravu UI.
Časté omyly
- MýtusVlákna vždycky zrychlí program.
- Ve skutečnostiVlákna zrychlí jen úlohy, které lze účinně rozdělit nebo které často čekají na I/O. U sdílených dat, častého zamykání nebo omezení runtime může být více vláken dokonce pomalejších.
- MýtusKdyž dám všude mutex, bude kód bezpečný.
- Ve skutečnostiMutex může zabránit některým závodům, ale nevylučuje deadlock, hladovění ani špatně navržené pořadí operací. Příliš hrubé zamykání navíc často odstraní výhodu paralelismu.
Časté dotazy
- Proč vlákno někdy nezrychlí výpočet?
- Vlákno někdy nezrychlí výpočet, protože výkon může omezovat jedno jádro, čekání na zámek, přístup do paměti nebo běhové prostředí jazyka. CPython má například GIL, který omezuje paralelní vykonávání běžného Python bytecodu v jednom procesu. Vlákna přesto často pomáhají u I/O úloh, kde program čeká na síť, disk nebo databázi.
- Co znamená, že je kód thread-safe?
- Thread-safe kód je kód, který se chová správně i při volání z více vláken současně. Thread-safe implementace chrání sdílený stav zámky, používá atomické operace, pracuje s neměnnými hodnotami nebo sdílí data přes fronty. Označení neznamená automaticky vysoký výkon, protože bezpečnost často přidává čekání nebo kopírování dat.
- Kolik vláken má aplikace spouštět?
- Počet vláken má vycházet z typu práce, omezení runtime a kapacity stroje. Výpočetně náročné úlohy obvykle nemají mít výrazně více běžících vláken než dostupných jader, jinak roste režie přepínání. I/O aplikace mohou snést více vláken, protože mnoho z nich čeká. Praktický limit se ověřuje měřením latence, propustnosti a spotřeby paměti.
- Proč vlákna způsobují deadlock?
- Deadlock vzniká, když vlákna čekají na prostředky v pořadí, které se navzájem zablokuje. Vlákno A například drží zámek databázové cache a čeká na zámek konfigurace, zatímco vlákno B drží zámek konfigurace a čeká na cache. Deadlock se omezuje pevným pořadím zamykání, časovými limity, menším sdílením stavu a jednodušší strukturou kritických sekcí.
Zdroje
- threading — Thread-based parallelism(otevře se v novém okně)
- Managed threading(otevře se v novém okně)
- Lesson: Concurrency(otevře se v novém okně)
- Thread (computing)(otevře se v novém okně)