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. |
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. |
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_lock
Klassen und reader_writer_lock::scoped_lock_read
Die Klassen reader_writer_lock::scoped_lock
verwenden, 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 |
---|---|
wait | 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.
Verwandte Abschnitte
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.