Semaphorobjekte
Ein Semaphorobjekt ist ein Synchronisierungsobjekt, das eine Anzahl zwischen Null und einem angegebenen Maximalwert beibehält. Die Anzahl wird jedes Mal erhöht, wenn ein Thread eine Wartezeit für das Semaphorobjekt abschließt und jedes Mal erhöht, wenn ein Thread das Semaphor loslässt. Wenn die Anzahl null erreicht, können keine weiteren Threads erfolgreich warten, bis der Semaphor-Objektzustand signalisiert wird. Der Zustand eines Semaphors wird so festgelegt, dass er signalisiert wird, wenn seine Anzahl größer als Null ist und nicht signalisiert wird, wenn die Anzahl null ist.
Das Semaphorobjekt ist nützlich beim Steuern einer freigegebenen Ressource, die eine begrenzte Anzahl von Benutzern unterstützen kann. Es fungiert als Gate, das die Anzahl der Threads begrenzt, die die Ressource auf eine angegebene maximale Anzahl teilen. Eine Anwendung kann beispielsweise die Anzahl der von ihr erstellten Fenster einschränken. Es verwendet ein Semaphor mit einer maximalen Anzahl, die dem Fensterlimit entspricht, und verringert die Anzahl, wenn ein Fenster erstellt und erhöht wird, wenn ein Fenster geschlossen wird. Die Anwendung gibt das Semaphorobjekt im Aufruf einer der Wartefunktionen an, bevor jedes Fenster erstellt wird. Wenn die Anzahl null ist – was angibt, dass die Fenstergrenze erreicht wurde – blockiert die Wartefunktion die Ausführung des Fenstererstellungscodes.
Ein Thread verwendet die CreateSemaphore oder CreateSemaphoreEx-Funktion, um ein Semaphorobjekt zu erstellen. Der erstellenden Thread gibt die anfängliche Anzahl und den Maximalwert der Anzahl für das Objekt an. Die anfängliche Anzahl darf weder kleiner als null noch größer als der Maximalwert sein. Der Erstellungsthread kann auch einen Namen für das Semaphorobjekt angeben. Threads in anderen Prozessen können ein Handle für ein vorhandenes Semaphorobjekt öffnen, indem er seinen Namen in einem Aufruf der OpenSemaphore--Funktion angibt. Weitere Informationen zu Namen für Mutex-, Ereignis-, Semaphor- und Timerobjekte finden Sie unter Interprocess Synchronization.
Wenn mehr als ein Thread auf ein Semaphor wartet, wird ein Wartethread ausgewählt. Gehen Sie nicht von einer First-In-First-Out-Reihenfolge (First-Out, FIFO) aus. Externe Ereignisse wie Kernelmodus-APCs können die Wartereihenfolge ändern.
Jedes Mal, wenn eine der Wartefunktionen zurückgegeben wird, da der Zustand eines Semaphors signalisiert wurde, wird die Anzahl des Semaphors um eins verringert. Die ReleaseSemaphor Funktion erhöht die Anzahl eines Semaphors um einen angegebenen Betrag. Die Anzahl darf niemals kleiner als Null oder größer als der Maximalwert sein.
Die anfängliche Anzahl eines Semaphors wird in der Regel auf den Maximalwert festgelegt. Die Anzahl wird dann von dieser Ebene erhöht, da die geschützte Ressource verbraucht wird. Alternativ können Sie ein Semaphor mit einer anfänglichen Anzahl von Null erstellen, um den Zugriff auf die geschützte Ressource zu blockieren, während die Anwendung initialisiert wird. Nach der Initialisierung können Sie ReleaseSemaphor- verwenden, um die Anzahl auf den Maximalwert zu erhöhen.
Ein Thread, der ein Mutex-Objekt besitzt, kann wiederholt warten, bis dasselbe Mutex-Objekt signalisiert wird, ohne dass die Ausführung blockiert wird. Ein Thread, der wiederholt auf dasselbe Semaphorobjekt wartet, verringert jedoch die Anzahl des Semaphors bei jedem Abschluss eines Wartevorgangs; der Thread wird blockiert, wenn die Anzahl auf Null wird. Ebenso kann nur der Thread, der ein Mutex besitzt, die ReleaseMutex-funktion aufrufen, obwohl jeder Thread ReleaseSemaphore verwenden kann, um die Anzahl eines Semaphorobjekts zu erhöhen.
Ein Thread kann die Anzahl eines Semaphors mehrmals erhöhen, indem wiederholt dasselbe Semaphorobjekt in Aufrufen einer der Wait-Funktionenangegeben wird. Das Aufrufen einer der Wait-Funktionen mit mehreren Objekten mit einem Array, das mehrere Handles desselben Semaphors enthält, führt jedoch nicht zu mehreren Schritten.
Wenn Sie mit der Verwendung des Semaphorobjekts fertig sind, rufen Sie die CloseHandle--Funktion auf, um den Handle zu schließen. Das Semaphorobjekt wird zerstört, wenn der letzte Griff geschlossen wurde. Das Schließen des Ziehpunkts wirkt sich nicht auf die Semaphoranzahl aus; Achten Sie daher darauf, ReleaseSemaphore aufzurufen, bevor Sie den Handle schließen oder bevor der Prozess beendet wird. Andernfalls werden ausstehende Wartezeitvorgänge entweder timeout oder unbegrenzt fortgesetzt, je nachdem, ob ein Timeoutwert angegeben wurde.
Verwandte Themen