Freigeben über


KeWaitForMultipleObjects-Funktion (wdm.h)

Die KeWaitForMultipleObjects-Routine versetzt den aktuellen Thread in einen warnbaren oder nicht verwertbaren Wartezustand, bis für eines oder alle einer Reihe von Dispatcherobjekten ein signalisierter Zustand festgelegt ist oder (optional) bis zum Timeout des Wartevorgangs.

Syntax

NTSTATUS
KeWaitForMultipleObjects (
    ULONG Count,
    PVOID Object[],
    WaitType,
    KWAIT_REASON WaitReason,
    KPROCESSOR_MODE WaitMode,
    BOOLEAN Alertable,
    PLARGE_INTEGER Timeout,
    PKWAIT_BLOCK WaitBlockArray
    );

Parameter

[in] Count

Die Anzahl der Objekte, auf die gewartet werden soll. Dieser Parameter gibt die Anzahl der Elemente im Array an, auf das der Object-Parameter verweist.

[in] Object

Ein Zeiger auf ein Array von Zeigern auf Verteilerobjekte (Ereignisse, Mutexe, Semaphore, Threads und Timer), für die der Aufrufer den Speicher bereitstellt. Sowohl das Zeigerarray als auch die Dispatcherobjekte müssen sich im nicht auslagerten Systemspeicher befinden. Weitere Informationen finden Sie in den Hinweisen.

[in] WaitType

Der Typ des auszuführenden Wartevorgangs. Geben Sie entweder WaitAll an, und geben Sie an, dass alle angegebenen Objekte einen Signalzustand erreichen müssen, bevor die Wartezeit erfüllt ist. oder WaitAny, die angibt, dass eines der Objekte einen signalierten Zustand erreichen muss, bevor die Wartezeit erfüllt ist.

[in] WaitReason

Der Grund für die Wartezeit. Treiber sollten diesen Wert auf Executive oder, wenn der Treiber im Namen eines Benutzers arbeitet und im Kontext eines Benutzerthreads ausgeführt wird, auf UserRequest festlegen.

[in] WaitMode

Gibt an, ob der Aufrufer in KernelMode oder UserMode wartet. Treiber der mittleren und niedrigsten Ebene sollten KernelMode angeben. Wenn die Gruppe von Objekten, auf die gewartet wird, einen Mutex enthält, muss der Aufrufer KernelMode angeben.

[in] Alertable

Ein boolescher Wert, der angibt, ob der Thread benachrichtigt werden kann, während er sich im Wartezustand befindet.

[in, optional] Timeout

Ein Zeiger auf einen Timeoutwert, der die absolute oder relative Zeit in 100 Nanosekundeneinheiten angibt, bei der die Wartezeit abgeschlossen werden soll.

Ein positiver Wert gibt eine absolute Zeit im Verhältnis zum 1. Januar 1601 an. Ein negativer Wert gibt ein Intervall relativ zur aktuellen Zeit an. Absolute Ablaufzeiten verfolgen alle Änderungen in der Systemzeit; relative Ablaufzeiten werden von Systemzeitänderungen nicht beeinflusst.

Wenn *Timeout = 0 ist, wird die Routine ohne Warten zurückgegeben. Wenn der Aufrufer einen NULL-Zeiger bereitstellt, wartet die Routine auf unbestimmte Zeit, bis ein oder alle Dispatcherobjekte auf den signalierten Zustand festgelegt sind. Weitere Informationen finden Sie im folgenden Abschnitt "Hinweise".

[out, optional] WaitBlockArray

Ein Zeiger auf ein aufruferseitig zugeordnetes KWAIT_BLOCK Array. Wenn Count<= THREAD_WAIT_OBJECTS, kann WaitBlockArrayNULL sein. Andernfalls muss dieser Parameter auf einen Speicherpuffer von sizeof(KWAIT_BLOCK) * Count bytes verweisen. Die Routine verwendet diesen Puffer für die Aufzeichnungsverwaltung während der Ausführung des Wartevorgangs. Der WaitBlockArray-Puffer muss sich im nicht auslagerten Systemspeicher befinden. Weitere Informationen finden Sie in den Hinweisen.

Rückgabewert

KeWaitForMultipleObjects kann eine der folgenden Rückgaben ausführen:

Rückgabecode Beschreibung
STATUS_SUCCESS Der Aufrufer hat WaitAll für den WaitType-Parameter angegeben, und alle Dispatcherobjekte im Object-Array wurden auf den signalierten Zustand festgelegt.
STATUS_ALERTED Die Wartezeit wurde unterbrochen, um eine Warnung an den aufrufenden Thread zu übermitteln.
STATUS_USER_APC Die Wartezeit wurde unterbrochen, um einen asynchronen Prozeduraufruf (User Asynchronous Procedure Call, APC) an den aufrufenden Thread zu übermitteln.
STATUS_TIMEOUT Ein Timeout ist aufgetreten, bevor der angegebene Satz von Wartebedingungen erfüllt wurde. Dieser Wert kann zurückgegeben werden, wenn ein expliziter Timeoutwert von 0 (null) angegeben wird, der angegebene Satz von Wartebedingungen jedoch nicht sofort erfüllt werden kann.
STATUS_WAIT_0 bis STATUS_WAIT_63 Der Aufrufer, der WaitAny für WaitType angegeben hat, und eines der Dispatcherobjekte im Object-Array wurde auf den signalierten Zustand festgelegt. Die unteren sechs Bits des Rückgabewerts codieren den nullbasierten Index des Objekts, das die Wartezeit erfüllt hat.
STATUS_ABANDONED_WAIT_0 bis STATUS_ABANDONED_WAIT_63 Der Aufrufer hat versucht, auf einen Mutex zu warten, der verlassen wurde. Die unteren sechs Bits des Rückgabewerts codieren den nullbasierten Index des Mutex im Object-Array .

Beachten Sie, dass das NT_SUCCESS Makro alle diese status Werte als "Erfolgswerte" erkennt.

Hinweise

Jedes Threadobjekt verfügt über ein integriertes Array von Warteblöcken, die verwendet werden können, um zu warten, bis mehrere Objekte gleichzeitig festgelegt werden. Wenn möglich, sollte das integrierte Array von Warteblöcken in einem mehrfachen Wartevorgang verwendet werden, da kein zusätzlicher Warteblockspeicher zugeordnet und später aufgehoben werden muss. Wenn jedoch die Anzahl der Objekte, auf die gleichzeitig gewartet werden muss, größer ist als die Anzahl der integrierten Warteblöcke, verwenden Sie den WaitBlockArray-Parameter , um einen alternativen Satz von Warteblöcken anzugeben, die im Wartevorgang verwendet werden sollen. Treiber müssen nur einen ausreichend großen Speicherpuffer für WaitBlockArray zuweisen. Der Puffer muss nicht initialisiert werden. Sie muss jedoch aus dem nicht auslagerten Systemspeicher zugeordnet werden. Wenn der WaitMode-ParameterUserMode ist, darf der WaitBlockArray-Puffer nicht auf dem lokalen Stapel zugeordnet werden, da der Stapel möglicherweise aus dem Arbeitsspeicher getauscht wird. Treiber können diesen Puffer als undurchsichtige Struktur behandeln und nach dem Zurückgeben der Routine freigeben. Wenn entweder Count> MAXIMUM_WAIT_OBJECTS oder WaitBlockArrayNULL und Count> THREAD_WAIT_OBJECTS ist, gibt das System Fehlerprüfung 0xC (MAXIMUM_WAIT_OBJECTS_EXCEEDED) aus.

Der aktuelle Zustand für jedes der angegebenen Objekte wird untersucht, um festzustellen, ob die Wartezeit sofort erfüllt werden kann. Wenn die erforderlichen Nebenwirkungen für die Objekte ausgeführt werden, wird ein entsprechender Wert zurückgegeben.

Wenn die Wartezeit nicht sofort erfüllt werden kann und entweder kein Timeoutwert oder ein Timeoutwert ungleich null angegeben wurde, wird der aktuelle Thread in einen Wartezustand versetzt, und ein neuer Thread wird für die Ausführung auf dem aktuellen Prozessor ausgewählt. Wenn kein Timeout angegeben wird, verbleibt der aufrufende Thread in einem Wartezustand, bis die von Object und WaitType angegebenen Bedingungen erfüllt sind.

Wenn Timeout angegeben wird, wird die Wartezeit automatisch erfüllt, wenn keine der angegebenen Wartebedingungen erfüllt ist, wenn das angegebene Intervall abläuft.

Ein Timeoutwert von 0 (null) ermöglicht das Testen einer Reihe von Wartebedingungen, sodass alle Nebenwirkungen bedingt ausgeführt werden, wenn die Wartezeit sofort erfüllt werden kann, z. B. beim Erwerb eines Mutex.

Timeoutintervalle werden relativ zur Systemuhr gemessen, und die Genauigkeit, mit der das Betriebssystem das Ende eines Timeoutintervalls erkennen kann, wird durch die Granularität der Systemuhr begrenzt. Weitere Informationen finden Sie unter Timergenauigkeit.

Der Alertable-Parameter bestimmt, wann der Thread gewarnt werden kann und sein Wartezustand folglich abgebrochen wird. Weitere Informationen finden Sie unter Wartevorgänge und APCs.

Das Array, auf das vom Objects-Parameter verwiesen wird, muss sich im nicht auslagerten Systemspeicher befinden. In der Regel ordnet ein Treiber den Speicher für das Objektarray im lokalen Stapel zu. Das Objects-Array kann unabhängig vom Wert des WaitMode-Parameters auf dem lokalen Stapel zugeordnet werden.

Die Dispatcherobjekte, auf die von den Elementen im Objects-Array verwiesen wird, müssen sich im nicht auslagerten Systemspeicher befinden. Wenn der WaitMode-ParameterUserMode ist, kann der Kernelstapel während der Wartezeit ausgetauscht werden. Folglich darf ein Aufrufer niemals versuchen, Parameter für den Stapel zu übergeben, wenn KeWaitForMultipleObjects mit dem Argument UserMode aufgerufen wird. Wenn Sie das Ereignis im Stapel zuordnen, müssen Sie den WaitMode-Parameter auf KernelMode festlegen.

Ein besonderer Aspekt gilt, wenn der anKeWaitForMultipleObjects übergebene Object-Parameter ein Mutex ist. Wenn das auf gewartete Verteilerobjekt ein Mutex ist, ist die APC-Übermittlung identisch mit allen anderen Verteilerobjekten während der Wartezeit. Nachdem KeWaitForMultipleObjects jedoch mit STATUS_SUCCESS zurückgibt und der Thread tatsächlich den Mutex enthält, werden nur spezielle Kernelmodus-APCs bereitgestellt. Die Übermittlung aller anderen APCs, sowohl im Kernelmodus als auch im Benutzermodus, ist deaktiviert. Diese Einschränkung für die Bereitstellung von APCs bleibt bestehen, bis der Mutex freigegeben wird.

Es ist besonders wichtig, den Rückgabewert von KeWaitForMultipleObjects zu überprüfen, wenn der WaitMode-ParameterUserMode oder AlertableTRUE ist, da KeWaitForMultipleObjects möglicherweise frühzeitig mit einer status von STATUS_USER_APC oder STATUS_ALERTED zurückgegeben wird.

Alle langfristigen Wartezeiten, die von einem Benutzer abgebrochen werden können, sollten userMode waits und Alertable auf FALSE festgelegt werden.

Wenn möglich, sollte Alertable auf FALSE und WaitMode auf KernelMode festgelegt werden, um die Treiberkomplexität zu verringern. Die Prinzipalausnahme besteht darin, wenn es sich bei der Wartezeit um eine langfristige Wartezeit handelt.

Ein Mutex kann nur zu MINLONG-Zeiten rekursiv erworben werden. Wenn dieser Grenzwert überschritten wird, löst die Routine eine STATUS_MUTANT_LIMIT_EXCEEDED Ausnahme aus.

Aufrufer von KeWaitForMultipleObjects können unter IRQL <= DISPATCH_LEVEL ausgeführt werden. Wenn Timeout = NULL oder *Timeout != 0 ist, muss der Aufrufer jedoch unter IRQL <= APC_LEVEL und in einem nicht-biträren Threadkontext ausgeführt werden. (Wenn Timeout != NULL und *Timeout = 0 sind, muss der Aufrufer unter IRQL <= DISPATCH_LEVEL ausgeführt werden.)

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Verfügbar ab Windows 2000.
Zielplattform Universell
Header wdm.h (einschließlich Wdm.h, Ntddk.h, Ntifs.h)
Bibliothek NtosKrnl.lib
DLL NtosKrnl.exe
IRQL Weitere Informationen finden Sie im Abschnitt mit den Hinweisen.
DDI-Complianceregeln HwStorPortProhibitedDDIs(storport), IrpProcessingComplete(wdm), IrqlKeWaitForMultipleObjects(wdm), SpNoWait(storport)

Weitere Informationen

ExInitializeFastMutex

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphor

KeInitializeTimer

KeWaitForSingleObject