Wait Functions
Wait-Funktionen zulassen, dass ein Thread seine eigene Ausführung blockiert. Die Wartefunktionen geben erst zurück, wenn die angegebenen Kriterien erfüllt wurden. Der Typ der Wartefunktion bestimmt die Menge der verwendeten Kriterien. Wenn eine Wartefunktion aufgerufen wird, überprüft sie, ob die Wartekriterien erfüllt wurden. Wenn die Kriterien nicht erfüllt wurden, gibt der aufrufende Thread den Wartezustand ein, bis die Bedingungen der Wartekriterien erfüllt wurden oder das angegebene Timeoutintervall verstrichen ist.
- Wait Functions
- Wait Functions mit mehreren Objekten
- Wartefunktionen
- registrierten Wartefunktionen
- warten auf eine Adresse
- Wartezeiten und Timeoutintervalle
- Warten von Funktionen und Synchronisierungsobjekten
- Warten von Funktionen und Erstellen von Windows
Wait Functions mit einem einzelnen Objekt
Die SignalObjectAndWait-, WaitForSingleObject-und WaitForSingleObjectEx- Funktionen erfordern ein Handle für ein Synchronisierungsobjekt. Diese Funktionen werden zurückgegeben, wenn eine der folgenden Aktionen auftritt:
- Das angegebene Objekt befindet sich im signalisierten Zustand.
- Das Timeoutintervall verstrichen. Das Timeoutintervall kann auf INFINITE- festgelegt werden, um anzugeben, dass das Warten kein Timeout ist.
Mit der SignalObjectAndWait--Funktion kann der aufrufende Thread den Zustand eines Objekts atomar festlegen, das signalisiert wird, und warten, bis der Zustand eines anderen Objekts auf das Signal festgelegt wird.
Wait Functions mit mehreren Objekten
Die WaitForMultipleObjects, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectsund MsgWaitForMultipleObjectsEx Funktionen ermöglichen es dem aufrufenden Thread, ein Array anzugeben, das ein oder mehrere Synchronisierungsobjekthandles enthält. Diese Funktionen werden zurückgegeben, wenn eine der folgenden Aktionen auftritt:
- Der Zustand eines der angegebenen Objekte wird auf signalisiert festgelegt, oder die Zustände aller Objekte wurden signalisiert. Sie steuern, ob ein oder alle Zustände im Funktionsaufruf verwendet werden.
- Das Timeoutintervall verstrichen. Das Timeoutintervall kann auf INFINITE- festgelegt werden, um anzugeben, dass das Warten kein Timeout ist.
Mit der MsgWaitForMultipleObjects und MsgWaitForMultipleObjectsEx--Funktion können Sie Eingabeereignisobjekte im Objekthandlearray angeben. Dies geschieht, wenn Sie den Typ der Eingabe angeben, auf die in der Eingabewarteschlange des Threads gewartet werden soll. Beispielsweise könnte ein Thread MsgWaitForMultipleObjects- verwenden, um die Ausführung zu blockieren, bis der Zustand eines angegebenen Objekts auf signalisiert festgelegt wurde und die Mauseingabe in der Eingabewarteschlange des Threads verfügbar ist. Der Thread kann die GetMessage- oder PeekMessageA- oder PeekMessageW- funktion verwenden, um die Eingabe abzurufen.
Wenn sie darauf warten, dass die Zustände aller Objekte auf das Signal festgelegt werden, ändern diese Mehrfachobjektfunktionen nicht die Zustände der angegebenen Objekte, bis die Zustände aller Objekte signalisiert wurden. Beispielsweise kann der Status eines Mutex-Objekts signalisiert werden, der aufrufende Thread erhält jedoch erst den Besitz, wenn die Zustände der anderen im Array angegebenen Objekte ebenfalls signalisiert wurden. In der Zwischenzeit erhält ein anderer Thread möglicherweise den Besitz des Mutex-Objekts, wodurch sein Zustand auf nicht signaliert festgelegt wird.
Wenn auf den Zustand eines einzelnen Objekts gewartet wird, das signalisiert wird, überprüfen diese Mehrfachobjektfunktionen die Ziehpunkte im Array, beginnend mit Index 0, bis eines der Objekte signalisiert wird. Wenn mehrere Objekte signalisiert werden, gibt die Funktion den Index des ersten Handles im Array zurück, dessen Objekt signalisiert wurde.
Warnbare Wartefunktionen
Die MsgWaitForMultipleObjectsEx, SignalObjectAndWait, WaitForMultipleObjectsExund WaitForSingleObjectEx Funktionen unterscheiden sich von den anderen Wartefunktionen, in denen sie optional einen warnbaren Wartevorgangausführen können. In einem warnbaren Wartevorgang kann die Funktion zurückgeben, wenn die angegebenen Bedingungen erfüllt sind, aber sie kann auch zurückgegeben werden, wenn das System eine E/A-Abschlussroutine oder ein APC für die Ausführung durch den Wartethread in die Warteschlange stellt. Weitere Informationen zu warnbaren Wartevorgängen und E/A-Vervollständigungsroutinen finden Sie unter Synchronisierung und überlappende Eingabe- und Ausgabe-. Weitere Informationen zu APCs finden Sie unter asynchronen Prozeduraufrufen.
Registrierte Wait-Funktionen
Die RegisterWaitForSingleObject Funktion unterscheidet sich von den anderen Wartefunktionen, in denen der Wartevorgang von einem Thread aus dem Threadpoolausgeführt wird. Wenn die angegebenen Bedingungen erfüllt sind, wird die Rückruffunktion von einem Workerthread aus dem Threadpool ausgeführt.
Standardmäßig ist ein registrierter Wartevorgang ein Mehrfachwartevorgang. Das System setzt den Timer jedes Mal zurück, wenn das Ereignis signalisiert wird (oder das Timeoutintervall verstrichen ist), bis Sie die UnregisterWaitEx--Funktion aufrufen, um den Vorgang abzubrechen. Um anzugeben, dass ein Wartevorgang nur einmal ausgeführt werden soll, legen Sie den dwFlags Parameter von RegisterWaitForSingleObject auf WT_EXECUTEONLYONCEfest.
Wenn der Thread Funktionen aufruft, die APCs verwenden, legen Sie den dwFlags Parameter von RegisterWaitForSingleObject auf WT_EXECUTEINPERSISTENTTHREADfest.
Warten auf eine Adresse
Ein Thread kann die WaitOnAddress-Funktion verwenden, um auf den Wert einer Zieladresse zu warten, um von einigen unerwünschten Werten in einen anderen Wert zu ändern. Dadurch können Threads warten, bis sich ein Wert ändert, ohne die Synchronisierungsprobleme zu drehen oder zu behandeln, die auftreten können, wenn der Thread einen unerwünschten Wert erfasst, der Wert jedoch geändert wird, bevor der Thread warten kann.
WaitOnAddress zurück, wenn Code, der den Zielwert ändert, die Änderung signalisiert, indem WakeByAddressSingle- aufgerufen wird, um einen einzelnen Wartethread zu reaktivieren, oder WakeByAddressAll, alle wartenden Threads zu reaktivieren. Wenn ein Timeoutintervall mit WaitOnAddress- angegeben wird und kein Thread eine Wake-Funktion aufruft, gibt die Funktion zurück, wenn das Timeoutintervall verstrichen ist. Wenn kein Timeoutintervall angegeben ist, wartet der Thread unbegrenzt.
Wartezeiten und Timeoutintervalle
Die Genauigkeit des angegebenen Timeoutintervalls hängt von der Auflösung der Systemuhr ab. Die Systemuhr "Ticks" mit konstanter Rate. Wenn das Timeoutintervall kleiner als die Auflösung der Systemuhr ist, kann die Wartezeit in weniger als der angegebenen Zeitdauer ausstehen. Wenn das Timeoutintervall größer als ein Teilstrich, aber weniger als zwei Teilstriche ist, kann die Wartezeit zwischen einem und zwei Teilstrichen usw. erfolgen.
Um die Genauigkeit des Timeoutintervalls für die Wartefunktionen zu erhöhen, rufen Sie die timeGetDevCaps--Funktion auf, um die unterstützte Minimale Timerauflösung und die timeBeginPeriod--Funktion festzulegen, um die Zeitgeberauflösung auf ihr Minimum festzulegen. Achten Sie beim Aufrufen timeBeginPeriod, da häufige Anrufe die Systemuhr, die Systemstromnutzung und den Zeitplan erheblich beeinträchtigen können. Wenn Sie timeBeginPeriodaufrufen, rufen Sie es einmal früh in der Anwendung auf, und achten Sie darauf, die timeEndPeriod--Funktion am Ende der Anwendung aufzurufen.
Wait-Funktionen und Synchronisierungsobjekte
Die Wait-Funktionen können die Zustände einiger Arten von Synchronisierungsobjektenändern. Änderungen treten nur für das Objekt oder die Objekte auf, deren signalisierter Zustand dazu führte, dass die Funktion zurückgegeben wurde. Wait-Funktionen können die Zustände von Synchronisierungsobjekten wie folgt ändern:
- Die Anzahl eines Semaphorobjekts verringert sich um ein Objekt, und der Zustand des Semaphors wird nicht signalisiert, wenn die Anzahl null ist.
- Die Zustände von Mutex-, Auto-Reset-Ereignis- und Änderungsbenachrichtigungsobjekten werden auf nichtsignaliert festgelegt.
- Der Zustand eines Synchronisierungszeitgebers wird auf nicht signaliert festgelegt.
- Die Zustände des manuellen Zurücksetzungsereignisses, des manuellen Zurücksetzens, des Prozesses, des Threads und der Konsoleneingabeobjekte sind von einer Wartefunktion nicht betroffen.
Warten von Funktionen und Erstellen von Windows
Sie müssen vorsichtig sein, wenn Sie die Wartefunktionen und den Code verwenden, der direkt oder indirekt Fenster erstellt. Wenn ein Thread Fenster erstellt, muss er Nachrichten verarbeiten. Nachrichtenübertragungen werden an alle Fenster im System gesendet. Wenn Sie über einen Thread verfügen, der eine Wartefunktion ohne Timeoutintervall verwendet, wird das System inaktiv. Zwei Beispiele für Code, der indirekt Fenster erstellt, sind DDE und die CoInitialize-Funktion. Wenn Sie über einen Thread verfügen, der Fenster erstellt, verwenden Sie daher MsgWaitForMultipleObjects oder MsgWaitForMultipleObjectsEx-anstelle der anderen Wartefunktionen.