共用方式為


自旋鎖簡介

自旋鎖是核心定義的、僅限於內核模式的同步機制,以不透明類型 KSPIN_LOCK 匯出。 自旋鎖可用來保護共享數據或資源免於同時存取。 在 IRQL <= DISPATCH_LEVEL 執行時,驅動程式可以使用 KeAcquireInStackQueuedSpinLockKeReleaseInStackQueuedSpinLock 來取得和釋放自旋鎖,作為一種佇列自旋鎖

或者,在 IRQL >= DISPATCH_LEVEL 上運行的調用者可以呼叫 KeAcquireSpinLockAtDpcLevelKeReleaseSpinLockFromDpcLevel,以提升驅動程式效能。

許多元件都使用自旋鎖,包括驅動程式。 任何類型的驅動程式的程式碼可能會使用一或多個 執行緒旋轉鎖。 例如,大多數檔案系統會在文件系統驅動程式(FSD)的裝置延伸模組中使用聯結工作佇列,以儲存由檔案系統的工作線程回呼例程和 FSD 共同處理的 IRP。 交錯的工作佇列受到執行層的旋轉鎖保護,這解決了 FSD 將 IRP 插入佇列時的競爭,以及任何嘗試同時移除 IRP 的線程之間的爭用問題。 另一個範例是,系統軟碟控制器驅動程式使用兩個執行旋轉鎖定。 一個主管自旋鎖用於保護與此驅動程式的裝置專用執行緒共用的聯鎖工作佇列;另一個用於保護由三個驅動程式例程共用的定時器物件。

佇列的微調鎖定比多處理器計算機上高競爭鎖定的一般微調鎖定提供更好的效能。 如需詳細資訊,請參閱 佇列旋轉鎖。 驅動程式也可以使用 KeAcquireSpinLockKeReleaseSpinLock 來像一般自旋鎖一樣取得和釋放自旋鎖。

為了同步存取簡單的數據結構,驅動程式可以使用任何 ExInterlockedXxx 函式,以確保數據結構的原子性存取。 使用這些例程的驅動程式不需要明確地取得或釋放自旋鎖。

擁有ISR的每個驅動程式都會使用 中斷微調鎖定 來保護其ISR與其 SynchCritSection 之間共用的任何數據或硬體 例程,這些例程會從其 StartIoDpcForIsr 例程呼叫。 中斷旋轉鎖與驅動程式呼叫 IoConnectInterrupt時所建立的中斷物件集相關聯,如註冊 ISR 一節中所述。

遵循下列指導方針,針對驅動程式中使用自旋鎖:

  • 提供受自旋鎖保護的任何數據或資源的儲存空間,以及在常駐系統空間記憶體中對應的自旋鎖(非分頁池,如 虛擬記憶空間和物理記憶體 圖所示)。 驅動程式必須為其使用的任何內部自旋鎖提供記憶體。 不過,裝置驅動程式不需要提供中斷微調鎖定的記憶體,除非它有多向量ISR或有一個以上的ISR,如註冊ISR中所述。

  • 呼叫 KeInitializeSpinLock,以初始化每個自旋鎖,這些鎖是由驅動程式提供存儲空間的,然後再使用它來同步存取其保護的共用數據或資源。

  • 在適當的 IRQL 中呼叫每個使用微調鎖定的支援例程,通常,對於管理階級微調鎖定,會在 <= DISPATCH_LEVEL 進行;而針對與驅動程式的中斷物件相關聯的中斷微調鎖定,則會在 <= DIRQL 呼叫。

  • 實施程序,以便在持有旋轉鎖定時儘可能快地執行。 任何例程都不應該保留超過 25 微秒的微調鎖定。

  • 切勿實作在持有自旋鎖時執行下列任何動作的例程:

    • 造成硬體例外狀況或引發軟體例外狀況。

    • 嘗試存取可分頁記憶體。

    • 進行一個遞迴呼叫,該呼叫可能導致死結或讓閃鎖持續保持超過 25 微秒。

    • 如果這樣做可能會導致死結,請嘗試取得另一個自旋鎖。

    • 呼叫違反上述任何規則的外部例程。