Kontexty

Tento dokument popisuje roli kontextů v modulu Concurrency Runtime. Vlákno připojené k plánovači se nazývá výkonný kontext 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 ustupují, nebo když chcete přetížit aktuální kontext.

Návod

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 uvolnit pro vykonávání všemi ostatními aktivními úkoly.

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

Třída concurrency::Context poskytuje programovací abstrakci pro kontext spuštění a nabízí dvě důležité vlastnosti: schopnost kooperativně blokovat, odblokovat a ustupovat aktuálnímu kontextu a schopnost nadřadit 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 uvolnění je užitečné, když aktuální kontext nemůže pokračovat kvůli nedostupnosti prostředků.

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 sám sebe.

Ke spolupráci při blokování a odblokování kontextu obvykle voláte concurrency::Context::CurrentContext, abyste získali ukazatel na Context objekt, který je přidružený k aktuálnímu vláknu, a uložíte 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 přiřadit každou dvojici volání k Context::Block a Context::Unblock. Modul runtime vyvolá concurrency::context_unblock_unbalanced, když je volána metoda Context::Block nebo Context::Unblock po sobě jdoucího bez odpovídajícího volání druhé metody. Před voláním Context::Unblock však nemusíte volat Context::Block. 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ý.

Metoda Concurrency::Context::Yield uvolní provádění, aby modul runtime mohl provádět jiné úlohy a následně znovu naplánovat kontext pro provedení. Při volání Context::Block metody modul runtime nepřeplánuje kontext.

Příklad

Příklad, který používá metody Context::Block, Context::Unblock a Context::Yield k implementaci třídy kooperativního semaforu, viz Jak: Použít třídu Context k implementaci kooperativního semaforu.

Překročení kapacity

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í výpočetně náročných se oversubscription obvykle neškáluje, protože zavádí dodatečnou režii. U úloh, které mají vysokou latenci, například čtení dat z disku nebo ze síťového připojení, může ale přetížení 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 podsazení, zavolejte metodu concurrency::Context::Oversubscribe s parametrem _BeginOversubscription nastaveným 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 budou dokončeny všechny úkoly vyžadující oversubscription, volejte Context::Oversubscribe s parametrem _BeginOversubscription 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ý úkol patří do stejného kontextu, povede k vytvoření dalšího vlákna pouze vnější volání na Context::Oversubscribe.

Poznámka:

Modul runtime vyvolá souběžnost::invalid_oversubscribe_operation, pokud je nadměrné přihlášení zakázáno před tím, než je povoleno.

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: Použití nadpřihlášení ke kompenzaci latence