Freigeben über


Kontexte

In diesem Dokument wird die Rolle von Kontexten in der Concurrency Runtime beschrieben. Der an einen Planer angefügte Thread wird als Ausführungskontext oder einfach als Kontext bezeichnet. Die concurrency::wait und die concurrency::Context-Funktion Klasse ermöglichen Ihnen, das Verhalten von Kontexten steuern. Mit der wait-Funktion können Sie den aktuellen Kontext für einen bestimmten Zeitraum unterbrechen. Mit der Context-Klasse können Sie die Kontrolle über Kontexte verbessern und diese leichter blockieren (bzw. die Blockierung aufzuheben) und zurückzuhalten und den aktuellen Kontext überzeichnen.

Tipp

Die Concurrency Runtime stellt einen Standardplaner bereit. Es ist daher nicht erforderlich, einen Planer in der Anwendung zu erstellen.Der Taskplaner ermöglicht eine genauere Steuerung der Leistung von Anwendungen. Aus diesem Grund wird empfohlen, mit der Parallel Patterns Library (PPL) oder der Asynchronous Agents Library zu beginnen, wenn Sie noch nicht mit der Concurrency Runtime vertraut sind.

Die wait-Funktion

Die concurrency::wait-Funktion ergibt kooperativ die Ausführung des aktuellen Kontext für eine angegebene Anzahl an Millisekunden. Der Zurückhaltungszeitraum wird zur Ausführung anderer Aufgaben genutzt. Nach Ablauf des angegebenen Zeitraums plant die Runtime die Kontextausführung neu. Aus diesem Grund kann die Unterbrechung des aktuellen Kontexts mit der wait-Funktion länger dauern als mit dem Wert für den milliseconds-Parameter angegeben.

Bei der Übergabe von 0 (null) für den milliseconds-Parameter unterbricht die Runtime den aktuellen Kontext, bis die Verarbeitung für alle anderen aktiven Kontexte ermöglicht wurde. Hiermit können Sie eine Aufgabe zugunsten von allen anderen aktiven Aufgaben zurückhalten.

Beispiel

Ein Beispiel, in dem der aktuelle Kontext mit der wait-Funktion zurückgehalten wird, damit andere Kontexte ausgeführt werden können, finden Sie unter Gewusst wie: Beeinflussen der Ausführungsreihenfolge mithilfe von Zeitplangruppen.

Die Context-Klasse

Die concurrency::Context-Klasse stellt eine Programmierabstraktion für einen Ausführungskontext sowie zwei weitere wichtige Features: die Möglichkeit, kooperativ zu blockieren, markieren die Blockierung und führen den aktuellen Kontext und zurückzuhalten und die Fähigkeit Kontext.

Kooperative Blockierung

Mit der Context-Klasse können Sie den aktuellen Ausführungskontext blockieren oder zurückhalten. Das Blockieren oder Zurückhalten ist nützlich, wenn der aktuelle Kontext nicht fortfahren kann, da eine Ressource nicht verfügbar ist.

Die concurrency::Context::Block-Methode blockieren Sie den aktuellen Kontext. Die Verarbeitungsressourcen des blockierten Kontexts werden zurückgehalten, sodass die Runtime andere Aufgaben ausführen kann. Die concurrency::Context::Unblock-Methode heben Sie die Blockierung eines blockierten Kontexts auf. Die Context::Unblock-Methode muss aus einem anderen Kontext aufgerufen werden als die Context::Block-Methode. Die Runtime löst concurrency::context_self_unblock aus, wenn ein Kontext versucht, die eigene Blockierung aufzuheben.

Um einen Kontext kooperativ zu blockieren und die Blockierung aufzuheben, rufen Sie in der Regel concurrency::Context::CurrentContext auf um einen Zeiger auf das Context-Objekt abzurufen das mit dem aktuellen Thread zugeordnet ist und das Ergebnis zu speichern. Mit der Context::Block-Methode können Sie den aktuellen Kontext blockieren. Um die Blockierung aufzuheben, rufen Sie zu einem späteren Zeitpunkt die Context::Unblock-Methode aus einem anderen Kontext auf.

Die Aufrufe der Context::Block-Methode und der Context::Unblock-Methode müssen immer paarweise erfolgen. Die Runtime löst concurrency::context_unblock_unbalanced aus, wenn die Methode Context::Block oder Context::Unblock nacheinander ohne einen entsprechenden Aufruf der jeweils anderen Methode aufgerufen wird. Sie müssen jedoch die Context::Block-Methode nicht zwingend vor der Context::Unblock-Methode aufrufen. Wenn aus einem Kontext beispielsweise die Context::Unblock-Methode aufgerufen wird, bevor aus einem anderen Kontext die Context::Block-Methode aufgerufen wird, erfolgt keine Blockierung des Kontexts.

Die concurrency::Context::Yield-Methode wird die Ausführung zurückgehalten, sodass die Runtime andere Aufgaben ausführen und dann die Ausführung des Kontexts neu planen kann. Wenn Sie die Context::Block-Methode aufrufen, wird der Kontext von der Laufzeit nicht neu geplant.

Beispiel

Ein Beispiel, in dem die Methoden Context::Block, Context::Unblock und Context::Yield verwendet werden, um eine kooperative Semaphorenklasse zu implementieren, finden Sie unter Gewusst wie: Implementieren einer kooperativen Semaphore mithilfe der Context-Klasse.

Überzeichnung

Die vom Standardplaner erstellte Anzahl an Threads stimmt mit der Anzahl der verfügbaren Hardwarethreads überein. Mithilfe der Überzeichnung können Sie zusätzliche Threads für einen gegebenen Hardwarethread erstellen.

Für rechenintensive Vorgänge ist die Überzeichnung nicht geeignet, da sie zusätzlichen Aufwand erfordert. Bei Aufgaben mit einer hohen Latenz, wie z. B. das Lesen von Daten von der Festplatte oder von einer Netzwerkverbindung, lässt sich die allgemeine Effizienz einiger Anwendungen mit der Überzeichnung jedoch durchaus verbessern.

Hinweis

Aktivieren Sie die Überzeichnung nur von einem Thread, der von der Concurrency Runtime erstellt wurde.Die Überzeichnung hat keine Auswirkungen, wenn sie in einem Thread aufgerufen wird, der nicht von der Runtime (einschließlich des Hauptthreads) erstellt wurde.

Um die Überzeichnung für den aktuellen Kontext zu aktivieren, rufen Sie die Methode concurrency::Context::Oversubscribe mit dem _BeginOversubscription-Parameter, der auf true festgelegt ist. Wenn Sie die Überzeichnung für einen von der Concurrency Runtime erstellten Thread aktivieren, erstellt die Runtime einen zusätzlichen Thread. Nachdem alle Aufgaben, die Überzeichnung erfordern, beendet wurden, rufen Sie die Context::Oversubscribe-Methode mit der _BeginOversubscription-Parametereinstellung false auf.

Sie können die Überzeichnung aus dem aktuellen Kontext mehrmals aktivieren, müssen die Überzeichnung aber immer genauso oft deaktivieren. Überzeichnung kann auch geschachtelt werden. Das heißt, der Kontext einer Aufgabe, die von einer anderen Aufgabe erstellt wird, kann auch überzeichnet werden. Wenn jedoch die geschachtelte und die übergeordnete Aufgabe dem gleichen Kontext zugeordnet sind, wird nur beim Aufruf von Context::Oversubscribe auf der jeweils obersten Ebene ein zusätzlicher Thread erstellt.

Hinweis

Die Runtime löst concurrency::invalid_oversubscribe_operation aus, wenn die Überzeichnung deaktivieren, bevor sie aktiviert wurde.

Beispiel

Ein Beispiel, in dem die Überzeichnung zum Kompensieren der Latenz beim Lesen von Daten von einer Netzwerkverbindung verwendet wird, finden Sie unter Gewusst wie: Verwenden der Überzeichnung zum Kompensieren der Latenz.

Siehe auch

Aufgaben

Gewusst wie: Beeinflussen der Ausführungsreihenfolge mithilfe von Zeitplangruppen

Gewusst wie: Implementieren einer kooperativen Semaphore mithilfe der Context-Klasse

Gewusst wie: Verwenden der Überzeichnung zum Kompensieren der Latenz

Konzepte

Taskplaner (Concurrency Runtime)