共用方式為


快速互斥鎖和受保護互斥鎖

從 Windows 2000 開始,驅動程式如果需要在 IRQL <= APC_LEVEL 執行的程式碼中使用低負擔的相互排除機制,則可以使用快速互斥鎖。 快速互斥鎖可以保護一次只能由一個執行緒輸入的程式碼路徑。 若要進入受保護的程式碼路徑,執行緒會 取得 互斥鎖。 如果另一個執行緒已取得互斥鎖,則會暫停目前執行緒的執行,直到釋放互斥鎖為止。 若要結束受保護的程式碼路徑,執行緒會 釋放 互斥鎖。

從 Windows Server 2003 開始,驅動程式也可以使用 受保護的互斥鎖。 防護的互斥鎖是高速互斥鎖的直接替代品,但在效能上表現更佳。 就像快速互斥鎖一樣,受保護的互斥鎖可以保護一次只能由一個執行緒輸入的程式碼路徑。 不過,使用受保護互斥鎖的程式碼比使用快速互斥鎖的程式碼執行得更快。

在 Windows 8 之前的 Windows 版本中,受保護的互斥鎖的實作方式與快速互斥鎖不同。 受快速互斥鎖保護的程式代碼路徑會在 IRQL = APC_LEVEL 執行。 受保護互斥鎖保護的程式碼路徑會在 IRQL <= APC_LEVEL 執行,但會停用所有 APC。 在這些舊版的 Windows 中,取得防護互斥鎖比取得快速互斥鎖更快。 不過,這兩種類型的互斥鎖在行為上相同,並受到相同的限制。 特別是,在 IRQL = APC_LEVEL 呼叫非法的核心常式不應該從受快速互斥鎖或受保護互斥鎖保護的程式代碼路徑呼叫。

從 Windows 8 開始,防護互斥鎖會被實作為快速互斥鎖。 在受保護互斥鎖或快速互斥鎖保護的程式碼路徑中,驅動程式驗證器 會將內核常式的呼叫視為發生在 IRQL = APC_LEVEL。 如同舊版 Windows 一樣,在受保護的互斥鎖或快速互斥鎖保護的程式代碼路徑中,APC_LEVEL 的非法呼叫仍然是非法的。

快速互斥

快速互斥鎖由 FAST_MUTEX 結構表示。 驅動程式會為 FAST_MUTEX 結構配置自己的記憶體,然後呼叫 ExInitializeFastMutex 常式來初始化結構。

執行緒會執行下列其中一項動作來取得快速互斥:

  • 呼叫 ExAcquireFastMutex 函式。 如果另一個執行緒已取得互斥鎖,則呼叫執行緒將被暫停執行,直到互斥鎖可用為止。

  • 呼叫 ExTryToAcquireFastMutex 常式,嘗試取得快速互斥鎖,而不暫停目前的執行緒。 程式程序會立即返回,不論是否已取得互斥鎖。 ExTryToAcquireFastMutex 如果成功取得呼叫端的互斥鎖,則會傳回 TRUE;否則,它會傳回 FALSE。

執行緒會呼叫 ExReleaseFastMutex 來釋放由 ExAcquireFastMutexExTryToAcquireFastMutex 所取得的快速互斥鎖。

受快速互斥鎖保護的程式代碼路徑會在 IRQL = APC_LEVEL 執行。 ExAcquireFastMutexExTryToAcquireFastMutex 會將目前的 IRQL 提高至 APC_LEVEL,而 ExReleaseFastMutex 會還原原始 IRQL。 因此,當線程保留快速互斥鎖時,所有 APC 都會被禁用。

如果程式代碼路徑保證一律以 APC_LEVEL 執行,驅動程式可以改為呼叫 ExAcquireFastMutexUnsafeExReleaseFastMutexUnsafe 來取得和釋放快速互斥鎖。 這些常式不會變更目前的 IRQL,而且只有當目前的 IRQL 為 APC_LEVEL 時才能安全地使用。

快速互斥鎖無法遞歸取得。 如果已經持有快速互斥鎖的執行緒嘗試再次取得該鎖,則該執行緒將會死鎖。 快速互斥鎖只能用於執行於 IRQL <= APC_LEVEL 的程式碼中。

受保護的互斥體

從 Windows Server 2003 開始提供的受保護的互斥鎖執行與快速互斥鎖相同的功能,但效能較高。

從 Windows 8 開始,受保護的互斥鎖和快速互斥鎖的實作方式相同。

在 Windows 8 之前的 Windows 版本中,受保護的互斥鎖的實作方式與快速互斥鎖不同。 取得快速互斥鎖時,會將目前的 IRQL 提升至 APC_LEVEL,而取得受保護的互斥鎖則會進入受保護區域,這是一個更快速的操作過程。 如需受防護區域的詳細資訊,請參閱 重要區域和受防護區域

受保護的互斥鎖由 KGUARDED_MUTEX 結構表示。 驅動程式會為 KGUARDED_MUTEX 結構配置自己的記憶體,然後呼叫 KeInitializeGuardedMutex 常式來初始化結構。

執行緒會執行下列其中一項動作來取得受保護的互斥鎖:

  • 呼叫 KeAcquireGuardedMutex。 如果另一個執行緒已取得互斥鎖,則呼叫執行緒將會被暫停,直到互斥鎖變得可用為止。

  • 呼叫 KeTryToAcquireGuardedMutex 嘗試獲取守護互斥體,而不暫停當前執行緒。 程式程序會立即返回,不論是否已取得互斥鎖。 KeTryToAcquireGuardedMutex 如果成功取得呼叫端的互斥鎖,則會傳回 TRUE。否則,它會傳回 FALSE

執行緒會呼叫 KeReleaseGuardedMutex 來釋放由 KeAcquireGuardedMutexKeTryToAcquireGuardedMutex 之一所取得的受保護互斥鎖。

擁有受保護互斥鎖的執行緒會隱含地在受保護區域內運行。 KeAcquireGuardedMutexKeTryToAcquireGuardedMutex 會進入受保護區域,而 KeReleaseGuardedMutex 會退出它。 當線程保留受保護的互斥鎖時,所有 APC 都會停用。

如果程式碼路徑在所有 APC 都已停用的情況下保證執行,那麼驅動程式可以選擇使用 KeAcquireGuardedMutexUnsafeKeReleaseGuardedMutexUnsafe 來獲取和釋放受保護的互斥體。 這些常式不會進入或結束受保護的區域,而且只能在現有的受保護區域內或 IRQL = APC_LEVEL 使用。

受保護的互斥鎖無法被遞迴取得。 如果已經持有防護互斥鎖的執行緒嘗試再次取得該鎖,該執行緒將會發生死結。 受保護的互斥鎖只能用於在 IRQL <= APC_LEVEL 執行的程式碼中。