KeWaitForMultipleObjects-Funktion (wdm.h)
Die KeWaitForMultipleObjects Routine versetzt den aktuellen Thread in einen warnbaren oder nicht veränderlichen Wartezustand, bis eine oder alle einer Reihe von Dispatcherobjekten auf einen signalisierten Zustand oder (optional) festgelegt sind, bis die Wartezeit ausfällt.
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 die der parameter Object verweist.
[in] Object
Ein Zeiger auf ein Array von Zeigern auf Dispatcherobjekte (Ereignisse, Mutexes, Semaphore, Threads und Timer), für die der Aufrufer den Speicher bereitstellt. Sowohl das Zeigerarray als auch die Dispatcherobjekte müssen sich im nicht seitenseitigen Systemspeicher befinden. Weitere Informationen finden Sie in den Hinweisen.
[in] WaitType
Der Typ des auszuführenden Wartevorgangs. Geben Sie entweder WaitAll-an, um anzugeben, dass alle angegebenen Objekte einen signalisierten Zustand erreichen müssen, bevor die Wartezeit erfüllt ist; oder WaitAny, der angibt, dass eines der Objekte einen signalisierten 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 Auftrag eines Benutzers arbeitet und im Kontext eines Benutzerthreads ausgeführt wird, auf UserRequest.
[in] WaitMode
Gibt an, ob der Aufrufer in KernelMode- oder UserMode-wartet. Treiber auf mittlerer und niedrigster Ebene sollten KernelMode-angeben. Wenn die Gruppe von Objekten, auf die gewartet wurde, 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 denen 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 Uhrzeit an. Absolute Ablaufzeiten verfolgen alle Änderungen der Systemzeit; Relative Ablaufzeiten sind von Systemzeitänderungen nicht betroffen.
Wenn *Timeout- = 0, wird die Routine ohne Warten zurückgegeben. Wenn der Aufrufer einen NULL- Zeiger bereitstellt, wartet die Routine unbegrenzt, 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 aufrufergeteilte KWAIT_BLOCK Array. Wenn Count<= THREAD_WAIT_OBJECTS, kann WaitBlockArray-NULL-sein. Andernfalls muss dieser Parameter auf einen Speicherpuffer mit Größe(KWAIT_BLOCK) * Anzahl Bytes verweisen. Die Routine verwendet diesen Puffer für die Datensatzhaltung beim Ausführen des Wartevorgangs. Der WaitBlockArray- Puffer muss sich im nicht ausgelagerten Systemspeicher befinden. Weitere Informationen finden Sie in den Hinweisen.
Rückgabewert
KeWaitForMultipleObjects kann eine der folgenden Werte zurückgeben:
Rückgabecode | Beschreibung |
---|---|
STATUS_SUCCESS | Der aufrufer, der WaitAll für den parameter WaitType und alle Dispatcherobjekte im Object Array auf den signalierten Zustand festgelegt wurde. |
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 (APC) des Benutzers an den aufrufenden Thread zu übermitteln. |
STATUS_TIMEOUT | Ein Timeout ist aufgetreten, bevor die angegebenen Wartebedingungen erfüllt wurden. Dieser Wert kann zurückgegeben werden, wenn ein expliziter Timeoutwert von Null angegeben wird, aber die angegebenen Wartezeitbedingungen können nicht sofort erfüllt werden. |
STATUS_WAIT_0 bis STATUS_WAIT_63 | Der Aufrufer hat WaitAny für WaitType angegeben, 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 abgebrochen 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 Statuswerte als "Erfolgswerte" erkennt.
Bemerkungen
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. Wann immer möglich, sollte das integrierte Array von Warteblöcken in einem Wait-Multiple-Vorgang verwendet werden, da kein zusätzlicher Warteblockspeicher zugewiesen und später zugeordnet werden muss. Wenn jedoch die Anzahl der Objekte, die gleichzeitig gewartet werden müssen, größer als die Anzahl der integrierten Warteblöcke ist, verwenden Sie den parameter WaitBlockArray, 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 nicht seitenseitigem Systemspeicher zugewiesen werden. Wenn der parameter WaitModeUserModeist, darf der WaitBlockArray Puffer nicht auf dem lokalen Stapel zugewiesen werden, da der Stapel möglicherweise aus dem Arbeitsspeicher getauscht wird. Treiber können diesen Puffer als undurchsichtige Struktur behandeln und nach der Rückgabe der Routine freigeben. Wenn entweder Count> MAXIMUM_WAIT_OBJECTS oder wenn WaitBlockArray-NULL- und Anzahl> THREAD_WAIT_OBJECTS ist, gibt das System Fehlerüberprüfung 0xC (MAXIMUM_WAIT_OBJECTS_EXCEEDED).
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 kein Timeoutwert 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 durch Object angegebenen Bedingungen und WaitType- erfüllt sind.
Wenn Timeout- angegeben ist, wird die Wartezeit automatisch erfüllt, wenn keine der angegebenen Wartezeitbedingungen erfüllt ist, wenn das angegebene Intervall abläuft.
Ein Timeoutwert von Null ermöglicht das Testen einer Reihe von Wartezeitbedingungen, bedingte Durchführung von Nebenwirkungen, wenn die Wartezeit sofort erfüllt werden kann, wie beim Erwerb eines Mutex.
Timeoutintervalle werden relativ zur Systemuhr gemessen, und die Genauigkeit, mit der das Betriebssystem das Ende eines Timeoutintervalls erkennen kann, ist durch die Granularität der Systemuhr begrenzt. Weitere Informationen finden Sie unter Zeitgebergenauigkeit.
Der parameter Alertable bestimmt, wann der Thread benachrichtigt werden kann und der Wartezustand daher abgebrochen wurde. Weitere Informationen finden Sie unter Waits and APCs.
Das Array, auf das der parameter Objects verweist, muss sich im nicht seitenseitigen Systemspeicher befinden. In der Regel weist ein Treiber den Speicher für das Objects Array 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 die Elemente im Objects Array verweisen, müssen sich im nicht seitenseitigen Systemspeicher befinden. Wenn der parameter WaitModeUserModeist, kann der Kernelstapel während der Wartezeit vertauscht werden. Folglich darf ein Aufrufer niemals versuchen, Parameter im Stapel zu übergeben, wenn KeWaitForMultipleObject s mit dem Argument UserMode aufgerufen wird. Wenn Sie das Ereignis auf dem Stapel zuweisen, müssen Sie den parameter WaitMode auf KernelMode-festlegen.
Eine besondere Berücksichtigung gilt, wenn der an KeWaitForMultipleObjects übergebene parameter Object ein Mutex ist. Wenn das dispatcher-Objekt, auf dem gewartet wurde, ein Mutex ist, ist die APC-Übermittlung identisch mit allen anderen Dispatcherobjekten während der Wartezeit. Nachdem KeWaitForMultipleObjects jedoch mit STATUS_SUCCESS zurückgegeben wurde und der Thread tatsächlich den Mutex enthält, werden nur spezielle Kernelmodus-APCs bereitgestellt. Die Übermittlung aller anderen APCs, sowohl vom Kernelmodus als auch vom 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 parameter WaitModeUserMode oder AlertableTRUEist, da KeWaitForMultipleObjects früh mit einem Status von STATUS_USER_APC oder STATUS_ALERTED zurückgegeben wird.
Alle langfristigen Wartezeiten, die von einem Benutzer abgebrochen werden können, sollten UserMode warte und warnungsfähige auf FALSE-festgelegt werden.
Wenn möglich, sollte warnungsfähige auf FALSE- und WaitMode- auf KernelMode-festgelegt werden, um die Treiberkomplexität zu verringern. Die Hauptausnahme hierfür ist, wenn die Wartezeit eine langfristige Wartezeit ist.
Ein Mutex kann rekursiv nur MINLONG-Zeiten 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 jedoch = NULL- oder *Timeout != 0 ausgeführt werden muss, muss der Aufrufer bei IRQL <= APC_LEVEL und in einem nichtarbiträren Threadkontext ausgeführt werden. (Wenn Timeout != NULL- und *Timeout- = 0 ist, muss der Aufrufer bei IRQL <= DISPATCH_LEVEL ausgeführt werden.)
Anforderungen
Anforderung | Wert |
---|---|
mindestens unterstützte Client- | Ab Windows 2000 verfügbar. |
Zielplattform- | Universal |
Header- | wdm.h (include Wdm.h, Ntddk.h, Ntifs.h) |
Library | NtosKrnl.lib |
DLL- | NtosKrnl.exe |
IRQL- | Siehe Abschnitt "Hinweise". |
DDI-Complianceregeln | HwStorPortProhibitedDDIs(storport), IrpProcessingComplete(wdm), IrqlKeWaitForMultipleObjects(wdm), SpNoWait(storport) |