Kontexty
Tento dokument popisuje roli kontextů v modulu Concurrency Runtime. Vlákno připojené k plánovači se označuje jako kontext spuštění nebo jen kontext. Funkce concurrency::wait a concurrency::Context třída umožňují řídit chování kontextů. wait
Funkce slouží k pozastavení aktuálního kontextu pro zadaný čas. Context
Třídu použijte, pokud potřebujete větší kontrolu nad tím, kdy kontexty blokují, odblokují a poskytují, nebo když chcete přepsat aktuální kontext.
Tip
Concurrency Runtime poskytuje výchozí plánovač, a proto ho v aplikaci nemusíte vytvářet. Vzhledem k tomu, že plánovač úloh pomáhá vyladit výkon vašich aplikací, doporučujeme začít knihovnou PPL (Parallel Patterns Library) nebo knihovnou asynchronních agentů , pokud s modulem Concurrency Runtime začínáte.
Funkce wait
Funkce concurrency::wait spoluvytáhá spuštění aktuálního kontextu pro zadaný počet milisekund. Modul runtime používá dobu výnosu k provádění dalších úloh. Po uplynutí zadaného času modul runtime přeplánuje kontext pro spuštění. wait
Funkce proto může pozastavit aktuální kontext déle, než je hodnota zadaná pro milliseconds
parametr.
Předání hodnoty 0 (nula) parametru milliseconds
způsobí, že modul runtime pozastaví aktuální kontext, dokud nebudou všechny ostatní aktivní kontexty poskytnuty příležitost k provádění práce. Díky tomu můžete úkol přinést všem ostatním aktivním úkolům.
Příklad
Příklad, který používá wait
funkci k získání aktuálního kontextu, a proto umožňuje spuštění jiných kontextů, viz Postupy: Použití skupin plánu k ovlivnění pořadí provádění.
Třída kontextu
Concurrency::Context třída poskytuje programovací abstrakci pro kontext spuštění a nabízí dvě důležité funkce: schopnost spolupracovat blokovat, odblokovat a poskytovat aktuální kontext a schopnost přepsat aktuální kontext.
Družstevní blokování
Třída Context
umožňuje blokovat nebo přinést aktuální kontext spuštění. Blokování nebo získávání je užitečné, když aktuální kontext nemůže pokračovat, protože prostředek není k dispozici.
Metoda concurrency::Context::Block blokuje aktuální kontext. Kontext, který je zablokovaný, poskytuje své prostředky zpracování, aby modul runtime mohl provádět další úlohy. Metoda concurrency::Context::Unblock odblokuje blokovaný kontext. Metoda Context::Unblock
musí být volána z jiného kontextu, než který volal Context::Block
. Modul runtime vyvolá souběžnost::context_self_unblock , pokud se kontext pokusí odblokovat.
Chcete-li spolupracovat blokovat a odblokovat kontext, obvykle voláte concurrency::Context::CurrentContext k načtení ukazatele na Context
objekt, který je přidružený k aktuálnímu vláknu a uloží výsledek. Pak zavoláte metodu Context::Block
, která zablokuje aktuální kontext. Později voláním Context::Unblock
z samostatného kontextu odblokujete blokovaný kontext.
Musíte shodovat jednotlivé dvojice volání do Context::Block
a Context::Unblock
. Modul runtime vyvolá souběžnost::context_unblock_unbalanced , pokud Context::Block
je volána nebo Context::Unblock
metoda po sobě jdoucí bez odpovídajícího volání druhé metody. Před voláním však nemusíte volat Context::Block
Context::Unblock
. Pokud například jeden kontext volá Context::Unblock
před voláním jiného kontextu Context::Block
pro stejný kontext, zůstane tento kontext odblokovaný.
Concurrency ::Context::Yield metoda poskytuje spuštění, aby modul runtime mohl provádět jiné úlohy a pak přeplánovat kontext pro spuštění. Při volání Context::Block
metody modul runtime nepřeplánuje kontext.
Příklad
Příklad, který používá , a metody k implementaci družstevní semaphore třídy, viz Postupy: Použití třídy context k implementaci družstevní semaphore.Context::Yield
Context::Unblock
Context::Block
Oversubscription
Výchozí plánovač vytvoří stejný počet vláken, jako jsou dostupná hardwarová vlákna. K vytvoření dalších vláken pro dané hardwarové vlákno můžete použít oversubscription .
U operací náročných na výpočetně se oversubscription obvykle nes škáluje, protože představuje další režii. U úloh, které mají vysokou latenci, například čtení dat z disku nebo ze síťového připojení, ale může přesazení zlepšit celkovou efektivitu některých aplikací.
Poznámka:
Povolte oversubscription pouze z vlákna vytvořeného modulem Concurrency Runtime. Oversubscription nemá žádný vliv, pokud je volán z vlákna, které nebylo vytvořeno modulem runtime (včetně hlavního vlákna).
Pokud chcete v aktuálním kontextu povolit oversubscription, zavolejte metodu concurrency::Context::Oversubscribe s parametrem nastaveným _BeginOversubscription
na true
. Když povolíte oversubscription ve vlákně vytvořeném modulem Concurrency Runtime, způsobí, že modul runtime vytvoří další vlákno. Poté, co všechny úkoly, které vyžadují dokončení oversubscription, volání Context::Oversubscribe
s _BeginOversubscription
parametrem nastaveným na false
.
Oversubscription můžete povolit vícekrát z aktuálního kontextu, ale musíte ho zakázat stejný počet, kolikrát ho povolíte. Oversubscription může být také vnořený; to znamená, že úkol vytvořený jiným úkolem, který používá oversubscription, může také přepsat jeho kontext. Pokud však vnořený úkol i jeho nadřazený prvek patří do stejného kontextu, způsobí vytvoření dalšího vlákna pouze vnější volání Context::Oversubscribe
.
Poznámka:
Modul runtime vyvolá souběžnost::invalid_oversubscribe_operation , pokud je před povolením zakázán oversubscription.
Příklad
Příklad, který používá oversubscription k posunu latence způsobené čtením dat ze síťového připojení, najdete v tématu Postupy: Použití oversubscription k posunu latence.
Viz také
Plánovač úloh
Postupy: Použití skupin plánů k ovlivnění pořadí provádění
Postupy: Použití třídy kontextu pro implementaci semaforu pro spolupráci
Postupy: Kompenzace latence vytvořením nadbytečného počtu vláken