Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Um Rennbedingungen und Deadlocks zu vermeiden, ist es notwendig, den Zugriff durch mehrere Threads mit freigegebenen Ressourcen zu synchronisieren. Die Synchronisierung ist auch erforderlich, um sicherzustellen, dass interdependent Code in der richtigen Sequenz ausgeführt wird.
Es gibt eine Reihe von Objekten, deren Handles zum Synchronisieren mehrerer Threads verwendet werden können. Zu diesen Objekten zählen:
- Konsolen-Eingabepuffer
- Ereignisse
- Mutexe
- Processes
- Semaphoren
- Themen
- Timer
Zusätzlich zu diesen wartenden Objekten stellt Windows einfache Synchronisierungsgrundtypen bereit, die keine Kernelhandles verwenden:
- Slim Reader/Writer (SRW)-Sperren – einfache Lese-/Schreibsperren für die intraprozessinterne Synchronisierung
- Bedingungsvariablen – Ermöglichen, dass Threads beim Freigeben einer Sperre auf eine Bedingung warten
- Verriegelte Funktionen – atomische Vorgänge für die sperrfreie Synchronisierung einfacher gemeinsam genutzter Variablen
Der Zustand der einzelnen Objekte wird entweder signalisiert oder nicht signalisiert. Wenn Sie ein Handle für eines dieser Objekte in einem Aufruf einer der Wartefunktionen angeben, wird die Ausführung des aufrufenden Threads blockiert, bis der Status des angegebenen Objekts signalisiert wird.
Einige dieser Objekte sind nützlich, um einen Thread zu blockieren, bis ein Ereignis eintritt. Beispielsweise befindet sich das Handle des Konsoleneingabepuffers im signalisierten Zustand, wenn noch nicht gelesene Eingaben vorhanden sind, z. B. ein Tastenanschlag oder ein Klick mit einer Maustaste. Prozess- und Threadhandles werden signalisiert, wenn der Prozess oder Thread beendet wird. Auf diese Weise kann ein Prozess beispielsweise einen untergeordneten Prozess erstellen und dann seine eigene Ausführung blockieren, bis der neue Prozess beendet wurde.
Andere Objekte sind nützlich, um gemeinsam genutzte Ressourcen vor gleichzeitigem Zugriff zu schützen. So können z. B. mehrere Threads über ein Handle für ein Mutex-Objekt verfügen. Bevor die Threads auf eine gemeinsam genutzte Ressource zugreifen, müssen sie eine der Wait-Funktionen aufrufen, um darauf zu warten, dass der Zustand des Mutex signalisiert wird. Wenn der Mutex signalisiert wird, wird nur ein wartenden Thread freigegeben, um auf die Ressource zuzugreifen. Der Status des Mutex wird sofort auf nicht signalisiert zurückgesetzt, sodass alle anderen Wartethreads blockiert bleiben. Wenn der Thread mit der Ressource fertig ist, muss er den Status des Mutex so festlegen, dass er signalisiert wird, damit andere Threads auf die Ressource zugreifen können.
Für die Threads eines einzelnen Prozesses bieten kritische Abschnittsobjekte eine effizientere Synchronisierungsmöglichkeit als Mutexes. Ein kritischer Abschnitt wird ähnlich wie ein Mutex eingesetzt, damit jeweils nur ein Thread gleichzeitig auf die geschützte Ressource zugreifen kann. Ein Thread kann die EnterCriticalSection-Funktion verwenden, um den Besitz eines kritischen Abschnitts anzufordern. Wenn er bereits einem anderen Thread gehört, wird der anfordernde Thread blockiert. Ein Thread kann die TryEnterCriticalSection-Funktion verwenden, um Besitz an einem kritischen Abschnitt zu beanspruchen, ohne bei einem Fehlschlag zum Abrufen des kritischen Abschnitts zu blockieren. Nachdem der Thread die Kontrolle übernommen hat, kann er die geschützte Ressource verwenden. Die Ausführung der anderen Threads des Prozesses wird nicht beeinflusst, es sei denn, sie versuchen, denselben kritischen Abschnitt zu betreten.
Die Funktion WaitForInputIdle veranlasst einen Thread, zu warten, bis ein angegebener Prozess initialisiert ist und auf Benutzereingaben wartet, ohne dass Eingaben ausstehen. Das Aufrufen von WaitForInputIdle kann nützlich sein, um übergeordnete und untergeordnete Prozesse zu synchronisieren, da CreateProcess zurückgegeben wird, ohne darauf zu warten, dass der untergeordnete Prozess die Initialisierung abgeschlossen hat.
Weitere Informationen finden Sie unter "Synchronisierung".