快速 Mutex 和受防護 Mutex

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

從 Windows Server 2003 開始,驅動程式也可以使用 受防護的 Mutex。 受防護的 Mutex 是快速 Mutex 的卸載取代專案,但可提供更佳的效能。 就像快速 Mutex 一樣,受防護 Mutex 可以保護一次只能由一個執行緒輸入的程式碼路徑。 不過,使用受防護 Mutex 的程式碼執行速度比使用快速 Mutex 的程式碼更快。

在Windows 8之前的 Windows 版本中,受防護的 mutex 會以不同于快速 Mutex 的方式實作。 由快速 mutex 保護的程式碼路徑會在 IRQL = APC_LEVEL執行。 受防護 Mutex 保護的程式碼路徑會在 IRQL < = APC_LEVEL執行,但停用所有 ABC。 在這些舊版的 Windows 中,取得受防護 Mutex 是比取得快速 Mutex 更快速的作業。 不過,這兩種類型的 Mutex 行為相同,而且受限於相同的限制。 特別是,在 IRQL = APC_LEVEL 呼叫不合法的核心常式不應從受快速 Mutex 或受防護 Mutex 保護的程式碼路徑呼叫。

從 Windows 8 開始,受防護的 mutex 會實作為快速 Mutex。 在受防護 Mutex 或快速 Mutex 保護的程式碼路徑中, 驅動程式驗證程式 會將核心常式的呼叫視為在 IRQL = APC_LEVEL 發生。 如同舊版 Windows,在APC_LEVEL時不合法的呼叫在受防護 Mutex 或快速 Mutex 保護的程式碼路徑中不合法。

快速 Mutex

快速 mutex 是由 FAST_MUTEX 結構表示。 驅動程式會為 FAST_MUTEX 結構配置自己的儲存體,然後呼叫 ExInitializeFastMutex 常式來初始化結構。

執行緒會執行下列其中一項來取得快速 Mutex:

  • 呼叫 ExAcquireFastMutex 常式。 如果已由另一個執行緒取得 mutex,則會暫停呼叫執行緒的執行,直到 mutex 變成可用為止。

  • 呼叫 ExTryToAcquireFastMutex 常式以嘗試取得快速 Mutex,而不暫停目前的執行緒。 不論是否已取得 mutex,常式都會立即傳回。 如果 ExTryToAcquireFastMutex 成功取得呼叫端的 mutex,則會傳回 TRUE ;否則會傳回 FALSE

執行緒會呼叫 ExReleaseFastMutex 來釋放 ExAcquireFastMutexExTryToAcquireFastMutex取得的快速 mutex。

由快速 mutex 保護的程式碼路徑會在 IRQL = APC_LEVEL執行。 ExAcquireFastMutexExTryToAcquireFastMutex 會引發目前的 IRQL APC_LEVEL,而 ExReleaseFastMutex 會還原原始 IRQL。 因此,執行緒會保留快速 Mutex 時停用所有 APC。

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

無法以遞迴方式取得快速 Mutex。 如果已經持有快速 Mutex 的執行緒嘗試取得它,該執行緒將會死結。 快速 mutex 只能用於在 IRQL < = APC_LEVEL執行的程式碼中。

受防護 Mutex

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

從 Windows 8 開始,受防護的 mutex 和快速 mutex 會以相同的方式實作。

在Windows 8之前的 Windows 版本中,受防護的 mutex 會以不同于快速 Mutex 的方式實作。 取得快速 mutex 會引發目前的 IRQL 來APC_LEVEL,同時取得受防護 Mutex 進入受防護的區域,這是較快速的作業。 如需受防護區域的詳細資訊,請參閱 重要區域和受防護區域

受防護 mutex 是由 KGUARDED_MUTEX 結構表示。 驅動程式會為 KGUARDED_MUTEX 結構配置自己的儲存體,然後呼叫 KeInitializeGuardedMutex 常式來初始化結構。

執行緒會執行下列其中一項動作,以取得受防護的 Mutex:

  • 呼叫 KeAcquireGuardedMutex。 如果已由另一個執行緒取得 mutex,則會暫停呼叫執行緒的執行,直到 mutex 變成可用為止。

  • 呼叫 KeTryToAcquireGuardedMutex 以嘗試取得受防護的 Mutex,而不暫停目前的執行緒。 不論是否已取得 mutex,常式都會立即傳回。 KeTryToAcquireGuardedMutex 如果成功取得呼叫端的 mutex,則會傳回 TRUE ;否則會傳回 FALSE

執行緒會呼叫 KeReleaseGuardedMutex 來釋放 KeAcquireGuardedMutexKeTryToAcquireGuardedMutex所取得的受防護 Mutex。

保存受防護 Mutex 的執行緒會隱含地在受防護區域內執行。 KeAcquireGuardedMutexKeTryToAcquireGuardedMutex 進入受防護的區域,而 KeReleaseGuardedMutex 則會結束它。 執行緒保留受防護 Mutex 時,會停用所有 APC。

如果保證在停用所有 APC 的情況下執行程式碼路徑,驅動程式可以改用 KeAcquireGuardedMutexUnsafeKeReleaseGuardedMutexUnsafe 來取得和釋放受防護 Mutex。 這些常式不會進入或結束受防護區域,而且只能用在已經存在的受防護區域或 IRQL = APC_LEVEL。

無法以遞迴方式取得受防護的 Mutex。 如果已經持有受防護 Mutex 的執行緒嘗試取得它,該執行緒將會死結。 受防護 mutex 只能用於在 IRQL < = APC_LEVEL執行的程式碼中。