Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Начиная с Windows 2000 драйверы могут использовать быстрые мьютекси , если им требуется низкая нагрузка для кода, работающего в IRQL <= APC_LEVEL. Быстрый мьютекс может защитить путь кода, который должен быть введен только одним потоком за раз. Чтобы ввести защищенный путь кода, поток получает мьютекс. Если другой поток уже захватил мьютекс, выполнение текущего потока приостановлено до освобождения мьютекса. Чтобы выйти из защищенного пути кода, поток освобождает мьютекс.
Начиная с Windows Server 2003 драйверы также могут использовать защищенные мьютексы. Защищенные мьютексы являются заменой с улучшенными характеристиками для быстрых мьютексов и обеспечивают лучшую производительность. Как и быстрый мьютекс, защищенный мьютекс может защитить путь кода, который должен быть введен только одним потоком за раз. Однако код, использующий защищенные мьютексы, выполняется быстрее, чем код, использующий быстрые мьютексы.
В версиях Windows до Windows 8 защищенные мьютексы реализуются иначе, чем быстрые мьютексы. Путь кода, защищенный быстрым мьютексом, выполняется на уровне IRQL = APC_LEVEL. Путь кода, защищенный защищенным мьютексом, выполняется в IRQL <= APC_LEVEL но со всеми отключенными API. В этих более ранних версиях Windows захват защищенного мьютекса происходит быстрее, чем захват быстрого мьютекса. Однако эти два типа мьютекса ведут себя одинаково и подвергаются одинаковым ограничениям. В частности, подпрограммы ядра, вызов которых запрещен на уровне IRQL = APC_LEVEL, нельзя вызывать из кода, защищенного fast mutex или защищенным мьютексом.
Начиная с Windows 8, защищённые мьютексы реализуются как быстрые мьютексы. В участке кода, защищенном мьютексом с защитой или быстрым мьютексом, средство проверки драйверов обрабатывает вызовы подпрограмм ядра, как если бы они выполнялись на уровне IRQL = APC_LEVEL. Как и в более ранних версиях Windows, вызовы, которые являются незаконными на уровне APC_LEVEL, также незаконны в пути выполнения кода, защищённом с помощью защищённого мьютекса или быстрого мьютекса.
Быстрые мьютексы
Быстрый мьютекс представлен структурой FAST_MUTEX . Драйвер выделяет собственное хранилище для структуры FAST_MUTEX , а затем вызывает подпрограмму ExInitializeFastMutex для инициализации структуры.
Поток получает быстрый мьютекс, выполнив одно из следующих действий:
Вызов подпрограммы ExAcquireFastMutex . Если мьютекс уже был приобретен другим потоком, выполнение вызывающего потока приостановлено до тех пор, пока мьютекс не станет доступным.
Вызов процедуры ExTryToAcquireFastMutex, чтобы попытаться получить быстрый мьютекс без приостановки текущего потока. Процедура возвращается немедленно, независимо от того, захвачен ли мьютекс. ExTryToAcquireFastMutex возвращает значение TRUE , если он успешно приобрел мьютекс для вызывающего объекта; в противном случае возвращает значение FALSE.
Поток вызывает ExReleaseFastMutex, чтобы освободить быстрый мьютекс, полученный либо ExAcquireFastMutex или ExTryToAcquireFastMutex.
Путь кода, защищенный быстрым мьютексом, выполняется в IRQL = APC_LEVEL. ExAcquireFastMutex и ExTryToAcquireFastMutex вызывают текущий IRQL до APC_LEVEL, а ExReleaseFastMutex восстанавливает исходный IRQL. Таким образом, все API отключены, пока поток содержит быстрый мьютекс.
В случае, если путь выполнения кода гарантированно всегда происходит на уровне APC_LEVEL, драйвер может вместо этого вызвать ExAcquireFastMutexUnsafe и ExReleaseFastMutexUnsafe, чтобы захватить и освободить быстрый мьютекс. Эти подпрограммы не изменяют текущий IRQL и могут безопасно использоваться только когда текущий IRQL равен APC_LEVEL.
Быстрые мьютекси нельзя получить рекурсивно. Если поток, который уже держит быстрый мьютекс, пытается получить его, этот поток будет заблокирован. В коде, работающем на IRQL <= APC_LEVEL, можно использовать только быстрые мьютексы.
Управляемые мьютексы
Защищенные мьютекси, доступные начиная с Windows Server 2003, выполняют ту же функцию, что и быстрые мьютекси, но с более высокой производительностью.
Начиная с Windows 8 защищенные мьютексы и быстрые мьютексы реализуются одинаково.
В версиях Windows до Windows 8 защищенные мьютексы реализуются иначе, чем быстрые мьютексы. При получении быстрого мьютекса повышает текущий IRQL до уровня APC_LEVEL, в то время как вход в защищенный регион происходит при получении защищенного мьютекса, что является более быстрой операцией. Дополнительные сведения о защищенных регионах см. в критически важных регионах и защищенных регионах.
Защищенный мьютекс представлен структурой KGUARDED_MUTEX . Драйвер выделяет собственное хранилище для структуры KGUARDED_MUTEX , а затем вызывает подпрограмму KeInitializeGuardedMutex для инициализации структуры.
Поток получает защищенный мьютекс, выполнив одно из следующих действий:
Вызов KeAcquireGuardedMutex. Если мьютекс уже был приобретен другим потоком, выполнение вызывающего потока будет приостановлено до тех пор, пока мьютекс не станет доступным.
Вызов KeTryToAcquireGuardedMutex , чтобы попытаться получить защищенный мьютекс без приостановки текущего потока. Рутина возвращается немедленно, независимо от того, был ли захвачен мьютекс. KeTryToAcquireGuardedMutex возвращает TRUE, если он успешно захватил мьютекс для вызывающего; в противном случае возвращает FALSE.
Поток вызывает KeReleaseGuardedMutex, чтобы освободить защищенный мьютекс, который был получен с помощью KeAcquireGuardedMutex или KeTryToAcquireGuardedMutex.
Поток, содержащий защищенный мьютекс, неявно работает в защищенной области. KeAcquireGuardedMutex и KeTryToAcquireGuardedMutex входят в защищенный регион, а KeReleaseGuardedMutex выходит из него. Все API отключены, пока поток содержит защищенный мьютекс.
Если путь кода гарантированно выполняется при отключении всех APC, драйвер может использовать KeAcquireGuardedMutexUnsafe и KeReleaseGuardedMutexUnsafe для получения и освобождения защищенного мьютекса. Эти подпрограммы не входят или выходят из защищенного региона и могут использоваться только в уже существующем защищенном регионе или в IRQL = APC_LEVEL.
Защищенные мьютексы нельзя получить рекурсивно. Если поток, который уже удерживает защищённый мьютекс, пытается снова его получить, произойдёт взаимоблокировка. Защищенные мьютексы можно использовать только в коде, работающем в IRQL <= APC_LEVEL.