KeWaitForMultipleObjects 函式 (wdm.h)
KeWaitForMultipleObjects 例程會將目前的線程置於可警示或不可變的等候狀態,直到任何或所有發送器物件都設定為訊號狀態或 (選擇性地) 直到等候逾時為止。
語法
NTSTATUS
KeWaitForMultipleObjects (
ULONG Count,
PVOID Object[],
WaitType,
KWAIT_REASON WaitReason,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout,
PKWAIT_BLOCK WaitBlockArray
);
參數
[in] Count
要等候的物件數目。 此參數會指定 Object 參數所指向之陣列中的項目數目。
[in] Object
發送器物件的指標陣列指標, (事件、mutexes、旗號、線程和定時器) ,呼叫端會為其提供記憶體。 指標數位和發送器對象都必須位於非分頁的系統記憶體中。 如需詳細資訊,請參閱<備註>。
[in] WaitType
要執行的等候作業類型。 指定 WaitAll,指出所有指定的物件都必須在滿足等候之前取得訊號狀態;或 WaitAny,表示任何一個對象都必須取得訊號狀態,才能滿足等候。
[in] WaitReason
等候的原因。 驅動程式應該將此值設定為 Executive ,或者,如果驅動程式代表使用者執行工作,並在使用者線程的內容中執行,則為 UserRequest。
[in] WaitMode
呼叫端是否在 KernelMode 或 UserMode 中等候。 中繼和最低層級驅動程序應該指定 KernelMode。 如果等候的物件集包含 mutex,則呼叫端必須指定 KernelMode。
[in] Alertable
布爾值,指出線程處於等候狀態時是否可以發出警示。
[in, optional] Timeout
以 100 奈秒單位指定等候完成之絕對或相對時間的逾時值指標。
正值會指定絕對時間,相對於 1601 年 1 月 1 日。 負值會指定相對於目前時間的間隔。 絕對到期時間會追蹤系統時間中的任何變更;相對到期時間不會受到系統時間變更的影響。
如果 *Timeout = 0,例程會傳回而不等候。 如果呼叫端提供 NULL 指標,則例程會無限期等候,直到任何或所有發送器物件都設定為訊號狀態為止。 如需詳細資訊,請參閱接下來的<備註>一節。
[out, optional] WaitBlockArray
呼叫端配置 KWAIT_BLOCK陣列的 指標。 如果 Count<= THREAD_WAIT_OBJECTS, 則 WaitBlockArray 可以是 NULL。 否則,此參數必須指向 大小為 sizeof 的記憶體緩衝區, (KWAIT_BLOCK) *計數 位元組。 例程會在執行等候作業時,使用此緩衝區進行記錄保留。 WaitBlockArray 緩衝區必須位於非分頁的系統記憶體中。 如需詳細資訊,請參閱<備註>。
傳回值
KeWaitForMultipleObjects 可以傳回下列其中一項:
傳回碼 | Description |
---|---|
STATUS_SUCCESS | 呼叫端指定 WaitType 參數的 WaitAll ,且 Object 陣列中的所有發送器物件都已設定為已發出訊號的狀態。 |
STATUS_ALERTED | 等候已中斷,以將警示傳遞給呼叫線程。 |
STATUS_USER_APC | 等候中斷,將使用者異步過程調用傳遞至呼叫線程 (APC) 。 |
STATUS_TIMEOUT | 在符合指定的等候條件集之前發生逾時。 指定明確逾時值為零時,可以傳回這個值,但無法立即符合指定的等候條件集。 |
STATUS_WAIT_0 到 STATUS_WAIT_63 | 呼叫端指定 WaitType 的 WaitAny,而 Object 陣列中的其中一個發送器物件已設定為已發出訊號的狀態。 傳回值的下六個位會編碼符合等候之物件之以零起始的索引。 |
透過STATUS_ABANDONED_WAIT_63 STATUS_ABANDONED_WAIT_0 | 呼叫端嘗試等候已放棄的 Mutex。 傳回值的下六位會編碼 Object 陣列中 Mutex 之以零起始的索引。 |
請注意,NT_SUCCESS宏會將所有這些狀態值辨識為「成功」值。
備註
每個線程物件都有一個內建的等候區塊陣列,可用來等候同時設定數個物件。 盡可能使用等候區塊的內建數位,應該在等候多重作業中使用,因為不需要配置額外的等候區塊記憶體,之後才解除分配。 不過,如果必須同時等候的物件數目大於內建等候區塊的數目,請使用 WaitBlockArray 參數來指定等候作業中要使用的替代等候區塊集。 驅動程式只需要為 WaitBlockArray 配置足夠的大型記憶體緩衝區。 緩衝區不需要初始化;不過,它必須從非分頁的系統記憶體配置。 如果 WaitMode 參數是 UserMode,則 WaitBlockArray 緩衝區不得配置在本機堆棧上,因為堆疊可能會交換掉記憶體。 驅動程式可以將這個緩衝區視為不透明結構,並在例程傳回之後釋放它。 如果 Count> MAXIMUM_WAIT_OBJECTS 或 WaitBlockArray 為 NULL 且 Count> THREAD_WAIT_OBJECTS,則系統會發出 錯誤檢查0xC (MAXIMUM_WAIT_OBJECTS_EXCEEDED) 。
會檢查每個指定物件的目前狀態,以判斷是否可以立即滿足等候。 如果對象上執行必要的副作用,則會傳回適當的值。
如果無法立即滿足等候,而且未指定逾時值或非零逾時值,則目前的線程會進入等候狀態,並選取新的線程在目前的處理器上執行。 如果未提供 逾 時,則呼叫線程會維持等候狀態,直到符合 Object 和 WaitType 所指定的條件為止。
如果指定 了 Timeout ,當指定的間隔到期時,如果未符合任何指定的等候條件,就會自動滿足等候。
零的逾時值允許測試一組等候條件,並有條件地在可以立即滿足等候時執行任何副作用,如同取得 mutex 一樣。
逾時間隔是相對於系統時鐘來測量,而操作系統可以偵測逾時間隔結束的精確度會受到系統時鐘的數據粒度所限制。 如需詳細資訊,請參閱 定時器精確度。
Alertable 參數會決定線程何時可以發出警示,以及其等候狀態因而中止。 如需詳細資訊,請參閱 等候和 APC。
Objects 參數所指向的數位必須位於非分頁的系統記憶體中。 一般而言,驅動程式會為本機堆疊上的 Objects 陣列配置記憶體。 不論 WaitMode 參數的值為何,對象陣列都可以配置在本機堆疊上。
Objects 陣列中的專案所指向的發送器對象必須位於非分頁的系統記憶體中。 如果 WaitMode 參數是 UserMode,則可以在等候期間交換核心堆疊。 因此,呼叫端在呼叫 KeWaitForMultipleObjects 搭配 UserMode 自變數時,絕對不能嘗試在堆疊上傳遞參數。 如果您在堆疊上配置事件,則必須將 WaitMode 參數設定為 KernelMode。
當傳遞至 KeWaitForMultipleObjects 的 Object 參數是 mutex 時,適用特殊考慮。 如果等候的發送器對像是 mutex,則 APC 傳遞與等候期間所有其他發送器物件相同。 不過,在 KeWaitForMultipleObjects 傳回STATUS_SUCCESS且線程實際保存 mutex 之後,只會傳遞特殊的核心模式 APC。 已停用核心模式和使用者模式的所有其他 APC 傳遞。 對 APC 傳遞的限制會持續存在,直到 Mutex 釋放為止。
當 WaitMode 參數為 UserMode 或 Alertable 為 TRUE 時,檢查 KeWaitForMultipleObjects 的傳回值特別重要,因為 KeWaitForMultipleObjects 可能會提早傳回狀態為 STATUS_USER_APC 或 STATUS_ALERTED。
用戶可中止的所有長期等候應該是 UserMode 等候, 而Alertable 應設定為 FALSE。
可能的話, Alertable 應該設定為 FALSE , 而 WaitMode 應該設定為 KernelMode,以減少驅動程式的複雜度。 此作業的主要例外狀況是等候是長期等候的時間。
Mutex 只能以遞歸方式取得MINLONG時間。 如果超過此限制,例程會引發STATUS_MUTANT_LIMIT_EXCEEDED例外狀況。
KeWaitForMultipleObjects 的呼叫端可以在 IRQL <= DISPATCH_LEVEL上執行。 不過,如果逾時NULL 或 *Timeout = != 0,呼叫端必須在 IRQL <= APC_LEVEL和非bitrary 線程內容中執行。 (如果 Timeout != NULL 和 *Timeout = 0,呼叫端必須在 IRQL <= DISPATCH_LEVEL.)
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | 從 Windows 2000 開始提供。 |
目標平台 | Universal |
標頭 | wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h) |
程式庫 | NtosKrnl.lib |
Dll | NtosKrnl.exe |
IRQL | 請參閱一節。 |
DDI 合規性規則 | HwStorPortProhibitedDIS (storport) 、 IrpProcessingComplete (wdm) 、 IrqlKeWaitForMultipleObjects (wdm) 、 SpNoWait (storport) |