Teilen über


Contexts

Dieses Dokument beschreibt die Rolle von Kontexten in den Laufzeiten Parallelität. Ein Thread, der an einen Scheduler angehängt ist, wird als Ausführungskontext bezeichnet oder einfach als Kontext. Mit der Parallelitätsfunktion::wait und der Parallelitätsklasse::Context können Sie das Verhalten von Kontexten steuern. Verwenden Sie die Funktion wait , um den aktuellen Kontext für eine bestimmte Zeit anzuhalten. Verwenden Sie die Klasse Context , wenn Sie mehr Kontrolle darüber benötigen, wann Kontexte blockiert, entsperrt und freigegeben werden, oder wenn Sie den aktuellen Kontext überschreiben möchten.

Tip

Die Concurrency Runtime stellt einen Standardplaner bereit. Sie müssen daher keinen in Ihrer Anwendung erstellen. Da Sie mit dem Scheduler die Leistung Ihrer Anwendungen optimieren können, empfehlen wir Ihnen, mit der Parallel Patterns Library (PPL) oder der Asynchronous Agents Library zu starten, wenn Sie mit Laufzeiten Parallelität noch nicht vertraut sind.

Die wait-Funktion

Die concurrency::wait gibt die Ausführung des aktuellen Kontexts für eine bestimmte Anzahl von Millisekunden kooperativ frei. Die Laufzeit nutzt die Auslagerungszeit, um andere Aufgaben auszuführen. Nach Ablauf der angegebenen Zeit plant die Laufzeit den Kontext für die Ausführung neu ein. Daher kann die Funktion wait den aktuellen Kontext länger als den für den Parameter milliseconds angegebenen Wert unterbrechen.

Wenn Sie für den Parameter milliseconds den Wert 0 (Null) übergeben, wird der aktuelle Kontext angehalten, bis alle anderen aktiven Kontexte die Möglichkeit hatten, ihre Arbeit auszuführen. Dadurch können Sie eine Aufgabe an alle anderen aktiven Aufgaben übergeben.

Beispiel

Wenn beispielsweise ein Kontext wait function to yield the current context, and thus allow for other contexts to run, see Anleitung: Verwenden von Zeitplan-Gruppen zum Beeinflussen der Reihenfolge der Ausführung.

Die Kontext-Klasse

Die concurrency::Context Klasse bietet eine Programmierabstraktion für einen Ausführungskontext und zwei wichtige Funktionen: die Möglichkeit, den aktuellen Kontext kooperativ zu blockieren, zu entsperren und zu übergeben, sowie die Möglichkeit, den aktuellen Kontext zu überschreiben.

Kooperative Blockierung

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

Die concurrency::Context::Block blockiert den aktuellen Kontext. Ein blockierter Kontext gibt seine Ressourcen für die Verarbeitung frei, sodass die Laufzeit andere Aufgaben ausführen kann. Die concurrency::Context::Unblock hebt die Blockierung eines blockierten Kontexts auf. Die Context::Unblock muss aus einem anderen Kontext aufgerufen werden als Context::Block. Die Laufzeit wirft concurrency::context_self_unblock , wenn ein Kontext versucht, sich selbst zu entsperren.

Um einen Kontext gemeinsam zu sperren und zu entsperren, rufen Sie in der Regel concurrency::Context::CurrentContext auf, um einen Zeiger auf das Context -Objekt abzurufen, das dem aktuellen Thread zugeordnet ist, und speichern das Ergebnis. Anschließend rufen Sie die Methode Context::Block auf, um den aktuellen Kontext zu blockieren. Rufen Sie anschließend Context::Unblock aus einem separaten Kontext auf, um den blockierten Kontext freizugeben.

Sie müssen jedes Paar zuordnen zu Aufrufen Context::Block und Context::Unblock. Die Laufzeit wirft concurrency::context_unblock_unbalanced aus, wenn die Methode Context::Block oder Context::Unblock nacheinander aufgerufen wird, ohne dass ein passender Aufruf der anderen Methode erfolgt ist. Sie müssen jedoch nicht Context::Block aufrufen, vor Context::Unblock. Wenn beispielsweise ein Kontext Context::Unblock aufruft, bevor ein anderer Kontext Context::Block für denselben Kontext aufruft, bleibt dieser Kontext nicht blockiert.

Die concurrency::Context::Yield gibt die Ausführung frei, sodass die Laufzeit andere Aufgaben ausführen und anschließend den Kontext für die Ausführung neu planen kann. Wenn Sie die Methode Context::Block aufrufen, plant die Laufzeit den Kontext nicht neu.

Beispiel

Ein Beispiel, in dem die Funktion Context::Block, Context::Unblockund Context::Yield zur Implementierung einer kooperativen Semaphor-Klasse finden Sie unter Anleitung: Verwenden der Kontextklasse zum Implementieren eines kooperativen Semaphors.

Überzeichnung

Der Standard-Scheduler erstellt dieselbe Anzahl an Threads, wie Hardware-Threads verfügbar sind. Mit Überzeichnung können Sie zusätzliche Threads für einen bestimmten Hardware-Thread erstellen.

Bei rechenintensiven Vorgängen ist eine Überbelegung in der Regel nicht sinnvoll, da sie zusätzliche Overhead-Kosten verursacht. Bei Aufgaben mit hoher Latenz, beispielsweise beim Lesen von Daten von Datenträgern oder über eine Netzwerkverbindung, kann eine Überbelegung jedoch die Gesamteffizienz einiger Anwendungen verbessern.

Note

Überbelegung nur von einem Thread aus aktivieren, der von den Laufzeiten Parallelität erstellt wurde. Eine Überzeichnung hat keine Auswirkungen, wenn sie von einem Thread aufgerufen wird, der nicht von der Laufzeit erstellt wurde (einschließlich des Haupt-Threads).

Um die Überzeichnung im aktuellen Kontext zu aktivieren, rufen Sie die Methode concurrency::Context::Oversubscribe mit dem _BeginOversubscription Parameter gesetzt auf true. Wenn Sie die Überbelegung für einen Thread aktivieren, der von den Laufzeiten Parallelität erstellt wurde, erstellt die Laufzeit einen zusätzlichen Thread. Nachdem alle Aufgaben, die eine Überzeichnung erfordern, abgeschlossen sind, führen Sie Context::Oversubscribe aus mit dem _BeginOversubscription Parameter gesetzt auf false.

Sie können die Überbelegung im aktuellen Kontext mehrmals aktivieren, müssen sie jedoch genauso oft deaktivieren, wie Sie sie aktiviert haben. Überbelegung kann auch verschachtelt sein, d. h. eine Aufgabe, die von einer anderen Aufgabe erstellt wurde, die Überbelegung verwendet, kann auch ihren Kontext überbelegen. Wenn jedoch sowohl eine verschachtelte Aufgabe als auch ihre übergeordnete Aufgabe zum selben Kontext gehören, führt nur der äußerste Aufruf von Context::Oversubscribe zur Erstellung eines zusätzlichen Threads.

Note

Die Laufzeit wirft concurrency::invalid_oversubscribe_operation aus, wenn die Überzeichnung deaktiviert wird, bevor sie aktiviert wurde.

Beispiel

Ein Beispiel für die Verwendung von Überabonnement zum Ausgleich der Latenz, die durch das Lesen von Daten aus einer Netzwerkverbindung verursacht wird, finden Sie unter Anleitung: Verwenden von Überabonnement zum Ausgleich der Latenz.

Weitere Informationen

Vorgangsplanung
Anleitung: Plangruppen verwenden, um die Reihenfolge der Ausführung zu beeinflussen
Vorgehensweise: Implementieren einer kooperativen Semaphore mithilfe der Context-Klasse
Vorgehensweise: Verwendung von Oversubscription zum Versetzen der Latenz