核心發送器物件的簡介

核心會定義一組稱為 核心發送器物件的物件類型,或只是 發送器物件。 發送器物件包括計時器物件、事件物件、旗號物件、mutex 物件和執行緒物件。

驅動程式可以使用發送器物件作為非bitrary 執行緒內容中的同步處理機制,同時在 IRQL 上執行等於PASSIVE_LEVEL。

Dispatcher 物件狀態

每個核心定義的發送器物件類型都有設定為 Signaled 或設定為 Not-Signaled 的狀態。

如果一或多個執行緒呼叫 KeWaitForSingleObjectKeWaitForMutexObjectKeWaitForMultipleObjects,執行緒群組可以同步處理其作業。 這些函式會採用發送器物件指標作為輸入,並等到另一個常式或執行緒將一或多個發送器物件設定為 Signaled 狀態為止。

當執行緒呼叫 KeWaitForSingleObject 以等候發送器物件 (或 KeWaitForMutexObject 進行 mutex) 時,執行緒會進入 等候 狀態,直到發送器物件設定為 Signaled 狀態為止。 執行緒可以呼叫 KeWaitForMultipleObjects 以等候任何或所有要設定為 Signaled 的發送器物件集。

每當發送器物件設定為 Signaled 狀態時,核心就會變更任何執行緒的狀態,等候該物件 就緒。 (同步處理計時器和同步處理事件是此規則的例外狀況;當同步處理事件或計時器收到訊號時,只有一個等候執行緒設定為就緒狀態。如需詳細資訊,請參閱計時器物件和 DPC 和事件物件.) 已就緒狀態的執行緒會根據其目前的執行時間執行緒優先順序,以及任何具有該優先順序之執行緒的處理器目前可用性來排程執行。

驅動程式何時可以等候發送器物件?

一般而言,只有在下列情況中至少有一個情況成立時,驅動程式才能等候發送器物件設定:

  • 驅動程式正在非bitrary 執行緒內容中執行。

    也就是說,您可以識別將進入等候狀態的執行緒。 實際上,在非bitrary 執行緒內容中執行的唯一驅動程式常式是 DriverEntryAddDeviceReinitializeUnload 常式,以及最高層級驅動程式的分派常式。 所有這些常式都是由系統直接呼叫。

  • 驅動程式正在執行完全同步的 I/O 要求。

    也就是說,在處理 I/O 要求時,沒有任何驅動程式會將任何作業排入佇列,而且在驅動程式下方的驅動程式完成處理要求之前,不會傳回任何驅動程式。

此外,如果驅動程式在 IRQL 執行于或高於 IRQL 等於DISPATCH_LEVEL,則無法進入等候狀態。

根據這些限制,您必須使用下列規則:

  • 任何驅動程式的 DriverEntryAddDeviceReinitializeUnload 常式都可以等候發送器物件。

  • 最高層級驅動程式的分派常式可以等候發送器物件。

  • 較低層級驅動程式的分派常式可以等候分派物件,如果 I/O 作業是同步的,例如建立、排清、關機和關閉作業、某些裝置 I/O 控制作業,以及一些 PnP 和電源作業。

  • 較低層級驅動程式的分派常式無法等候發送器物件完成非同步 I/O 作業。

  • 在 IRQL 或更新版本執行的驅動程式常式DISPATCH_LEVEL不得等候發送器物件設定為 Signaled 狀態。

  • 驅動程式不得嘗試等候發送器物件設定為 Signaled 狀態,以完成移轉作業到分頁裝置或從分頁裝置完成。

  • 驅動程式分派常式服務讀取/寫入要求通常無法等候發送器物件設定為 Signaled 狀態。

  • 裝置 I/O 控制要求的分派常式只能等候發送器物件設定為 Signaled 狀態,只有當 I/O 控制項程式碼的傳輸類型METHOD_BUFFERED時。

  • SCSI 迷你埠驅動程式不應該使用核心發送器物件。 SCSI 迷你埠驅動程式應該只呼叫 SCSI 埠程式庫常式

所有其他標準驅動程式常式都會在任意執行緒內容中執行:當呼叫驅動程式常式來處理佇列作業或處理裝置中斷時,任何執行緒都會發生目前的情況。 此外,大部分的標準驅動程式常式都是在引發的 IRQL 上執行,不論是在 DISPATCH_LEVEL,或是在 DIRQL 的設備磁碟機上執行。

如有必要,驅動程式可以建立裝置專用線程,該執行緒可以等候驅動程式的其他常式 (,但 ISR 或 SynchCritSection 常式除外,) 將發送器物件設定為 Signaled 狀態,並重設為Not-Signaled狀態。

一般指導方針是,如果您預期新的設備磁碟機在 I/O 作業期間等候裝置狀態變更時,通常需要停止超過 50 毫秒,請考慮使用裝置專用線程來實作驅動程式。 如果裝置驅動程式也是最高階驅動程式,請考慮使用 系統背景工作執行緒 並實作一或多個背景工作執行緒回呼常式。 請參閱 PsCreateSystemThread使用Driver-Created執行緒管理連結佇列