Freigeben über


Synchronisierungsdatenstrukturen

Die Parallelitätslaufzeit bietet mehrere Datenstrukturen, mit denen Sie den Zugriff auf freigegebene Daten aus mehreren Threads synchronisieren können. Diese Datenstrukturen sind nützlich, wenn Sie freigegebene Daten haben, die Sie selten ändern. Ein Synchronisierungsobjekt, z. B. ein kritischer Abschnitt, bewirkt, dass andere Threads warten, bis die freigegebene Ressource verfügbar ist. Wenn Sie daher ein solches Objekt verwenden, um den Zugriff auf häufig verwendete Daten zu synchronisieren, können Sie die Skalierbarkeit in Ihrer Anwendung verlieren. Die Parallel Patterns Library (PPL) stellt die parallele Klasse ::kombinationsfähige Klasse bereit, mit der Sie eine Ressource für mehrere Threads oder Vorgänge freigeben können, ohne dass eine Synchronisierung erforderlich ist. Weitere Informationen zur combinable Klasse finden Sie unter Parallel Containers and Objects.

Abschnitte

In diesem Thema werden die folgenden asynchronen Nachrichtenblocktypen ausführlich beschrieben:

critical_section

Die Parallelität::critical_section Klasse stellt ein kooperatives gegenseitiges Ausschlussobjekt dar, das anderen Aufgaben ergibt, anstatt sie zu überschreiben. Kritische Abschnitte sind nützlich, wenn mehrere Threads exklusiven Lese- und Schreibzugriff auf freigegebene Daten erfordern.

Die critical_section Klasse ist nicht erneut aktiviert. Die Parallelität::critical_section::lock-Methode löst eine Ausnahme vom Typ "Parallelität::improper_lock " aus, wenn sie vom Thread aufgerufen wird, der die Sperre bereits besitzt.

Methoden und Features

In der folgenden Tabelle sind die wichtigen Methoden aufgeführt, die von der critical_section Klasse definiert werden.

Methode Beschreibung
lock Erwirbt den kritischen Abschnitt. Der aufrufende Kontext wird blockiert, bis er die Sperre erhält.
try_lock Versucht, den kritischen Abschnitt zu erwerben, aber nicht blockiert.
unlock Gibt den kritischen Abschnitt frei.

[Nach oben]

reader_writer_lock

Die Parallelität::reader_writer_lock Klasse stellt threadsichere Lese-/Schreibvorgänge für freigegebene Daten bereit. Verwenden Sie Lese-/Schreibsperren, wenn mehrere Threads gleichzeitigen Lesezugriff auf eine freigegebene Ressource erfordern, aber selten in diese freigegebene Ressource schreiben. Mit dieser Klasse wird jeweils nur ein Thread-Schreibzugriff auf ein Objekt gewährt.

Die reader_writer_lock Klasse kann besser als die critical_section Klasse ausgeführt werden, da ein critical_section Objekt exklusiven Zugriff auf eine freigegebene Ressource erhält, wodurch gleichzeitiger Lesezugriff verhindert wird.

Wie die critical_section Klasse stellt die reader_writer_lock Klasse ein kooperatives gegenseitiges Ausschlussobjekt dar, das andere Aufgaben zurückgibt, anstatt sie vorzubelassen.

Wenn ein Thread, der in eine freigegebene Ressource schreiben muss, eine Lese-/Schreibsperre erhält, werden andere Threads, die ebenfalls auf die Ressource zugreifen müssen, blockiert, bis der Writer die Sperre loslässt. Die reader_writer_lock Klasse ist ein Beispiel für eine Schreibeinstellungssperre , bei der es sich um eine Sperre handelt, die die Blockierung von Schreibautoren entsperrt, bevor die Blockierung der wartenden Leser aufgehoben wird.

Wie die critical_section Klasse ist die reader_writer_lock Klasse nicht erneut. Die Parallelität::reader_writer_lock::lock und parallelität::reader_writer_lock::lock_read Methoden lösen eine Ausnahme vom Typ improper_lock aus, wenn sie von einem Thread aufgerufen werden, der die Sperre bereits besitzt.

Hinweis

Da die reader_writer_lock Klasse nicht erneut aktiviert ist, können Sie eine schreibgeschützte Sperre nicht auf eine Lese-/Schreibsperre aktualisieren oder eine Lese-/Schreibsperre auf eine schreibgeschützte Sperre herabstufen. Das Ausführen einer dieser Vorgänge erzeugt ein nicht angegebenes Verhalten.

Methoden und Features

In der folgenden Tabelle sind die wichtigen Methoden aufgeführt, die von der reader_writer_lock Klasse definiert werden.

Methode Beschreibung
lock Erwirbt Lese-/Schreibzugriff auf die Sperre.
try_lock Versucht, Lese-/Schreibzugriff auf die Sperre zu erhalten, blockiert jedoch nicht.
lock_read Erwirbt schreibgeschützten Zugriff auf die Sperre.
try_lock_read Versucht, schreibgeschützten Zugriff auf die Sperre zu erhalten, aber nicht blockiert.
unlock Gibt die Sperre frei.

[Nach oben]

scoped_lock und scoped_lock_read

Die critical_section Klassen und reader_writer_lock Klassen stellen geschachtelte Hilfsklassen bereit, die das Arbeiten mit gegenseitigen Ausschlussobjekten vereinfachen. Diese Hilfsklassen werden als bereichsbezogene Sperren bezeichnet.

Die critical_section Klasse enthält die Parallelität::critical_section::scoped_lock Klasse. Der Konstruktor erhält Zugriff auf das bereitgestellte critical_section Objekt. Der Destruktor gibt zugriff auf dieses Objekt frei. Die reader_writer_lock Klasse enthält die Parallelität::reader_writer_lock::scoped_lock Klasse, die ähnlich ist critical_section::scoped_lock, mit der Ausnahme, dass der Schreibzugriff auf das bereitgestellte reader_writer_lock Objekt verwaltet wird. Die reader_writer_lock Klasse enthält auch die Parallelität::reader_writer_lock::scoped_lock_read Klasse. Diese Klasse verwaltet lesezugriff auf das bereitgestellte reader_writer_lock Objekt.

Bereichssperren bieten mehrere Vorteile, wenn Sie manuell mit critical_section Objekten reader_writer_lock arbeiten. In der Regel weisen Sie eine bereichsbezogene Sperre auf dem Stapel zu. Eine bereichsbezogene Sperre gibt den Zugriff auf sein gegenseitiges Ausschlussobjekt automatisch frei, wenn es zerstört wird; Daher entsperren Sie das zugrunde liegende Objekt nicht manuell. Dies ist nützlich, wenn eine Funktion mehrere return Anweisungen enthält. Mit bereichsbezogenen Sperren können Sie auch ausnahmesicheren Code schreiben. Wenn eine throw Anweisung bewirkt, dass der Stapel abweicht, wird der Destruktor für eine aktive bereichsbezogene Sperre aufgerufen, und daher wird das gegenseitige Ausschlussobjekt immer korrekt freigegeben.

Hinweis

Wenn Sie die critical_section::scoped_lockKlassen und reader_writer_lock::scoped_lock_read Die Klassen reader_writer_lock::scoped_lockverwenden, lassen Sie den Zugriff auf das zugrunde liegende gegenseitige Ausschlussobjekt nicht manuell frei. Dadurch kann die Laufzeit in einen ungültigen Zustand versetzt werden.

event

Die Parallelitätsklasse::event stellt ein Synchronisierungsobjekt dar, dessen Zustand signalisiert oder nicht signalisiert werden kann. Im Gegensatz zu Synchronisierungsobjekten, z. B. kritische Abschnitte, deren Zweck es ist, den Zugriff auf freigegebene Daten zu schützen, synchronisieren Ereignisse den Ausführungsfluss.

Die event Klasse ist nützlich, wenn eine Aufgabe Arbeit für eine andere Aufgabe abgeschlossen hat. Beispielsweise kann eine Aufgabe eine andere Aufgabe signalisieren, dass sie Daten aus einer Netzwerkverbindung oder aus einer Datei gelesen hat.

Methoden und Features

In der folgenden Tabelle sind mehrere der wichtigen Methoden aufgeführt, die von der event Klasse definiert werden.

Methode Beschreibung
Warte Wartet, bis das Ereignis signalisiert wird.
set Legt das Ereignis auf den signalierten Zustand fest.
reset Legt das Ereignis auf den nicht signalgesteuerten Zustand fest.
wait_for_multiple Wartet, bis mehrere Ereignisse signalisiert werden.

Beispiel

Ein Beispiel für die Verwendung der event Klasse finden Sie unter "Vergleichen von Synchronisierungsdatenstrukturen" mit der Windows-API.

[Nach oben]

Vergleich der Synchronisierungsdatenstrukturen mit der Windows-API
Vergleicht das Verhalten der Synchronisierungsdatenstrukturen mit denen, die von der Windows-API bereitgestellt werden.

Concurrency Runtime
Beschreibt die Concurrency Runtime, die die parallele Programmierung vereinfacht, und stellt Links zu verwandten Themen bereit.