Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Любой драйвер может использовать объект семафора для синхронизации операций между созданными драйвером потоками и другими подпрограммами драйверов. Например, выделенный драйвером поток может поместить себя в состояние ожидания, если отсутствуют невыполненные запросы ввода-вывода для драйвера, и подпрограммы отправки драйвера могут задать семафор в состояние signaled сразу после очереди IRP.
Подпрограммы отправки драйверов высокого уровня, которые выполняются в контексте потока, запрашивающего операцию ввода-вывода, могут использовать семафор для защиты ресурса, общего между подпрограммами отправки. Подпрограммы диспетчеризации драйверов нижнего уровня для синхронных операций ввода-вывода также могут использовать семафор для защиты ресурса, доступного между этим подмножеством подпрограмм отправки или с помощью потока, созданного драйвером.
Любой драйвер, использующий объект семафора, должен вызывать KeInitializeSemaphore, прежде чем он ожидает или освобождает семафор. На следующем рисунке показано, как драйвер с потоком может использовать объект семафора.
Как показано на предыдущем рисунке, такой драйвер должен предоставить хранилище для объекта семафора, который должен быть резидентом. Драйвер может использовать расширение устройства объекта устройства, созданного драйвером, расширение контроллера, если он использует объект контроллера или непагированные пулы, выделенные драйвером.
Когда AddDevice драйвера подпрограммы вызывает KeInitializeSemaphore, он должен передать указатель на резидентное хранилище драйвера для объекта семафора. Кроме того, вызывающий объект должен указать Count для объекта семафора, как показано на предыдущем рисунке, определяющее начальное состояние (ненулевое значение для Signaled).
Вызывающий объект также должен указать предел для семафора, который может быть следующим:
ограничение = 1
Если для этого семафора задано состояние Signaled, один поток, ожидающий установки семафора, становится допустимым для выполнения и может получить доступ к любым ресурсам, защищенным семафором.
Этот тип семафора также называется двоичным семафором, так как поток либо имеет или не имеет монопольного доступа к ресурсу, защищенному семафором.
ограничение > 1
Если для этого семафора задано состояние Signaled, некоторые потоки, ожидающие установки объекта семафора, становятся допустимыми для выполнения и могут получить доступ к любым ресурсам, защищенным семафором.
Этот тип семафора называется подсчетом семафора, так как подпрограмма, которая задает семафору состояние Signaled, также указывает, сколько потоков ожидания может измениться от ожидания до готовности. Число таких потоков ожидания может быть ограничение, заданное при инициализации семафора или некоторое число меньше, чем это предустановленное Предел.
Несколько драйверов устройств или промежуточных драйверов имеют один поток, созданный драйвером; даже меньшее количество потоков, которые могут ожидать получения или освобождения семафора. Немногие системные драйверы используют объекты семафора, а из тех, которые делают, даже меньше использовать двоичный семафор. Хотя двоичный семафор может быть похож на функциональные возможности объекта мьютекса, двоичный семафор не обеспечивает встроенную защиту от взаимоблокировок, которые объект мьютекса имеет для системных потоков, работающих на компьютерах SMP.
После загрузки драйвера с инициализированной семафоры он может синхронизировать операции семафора, защищающего общий ресурс. Например, драйвер с выделенным устройством потоком, который управляет очередью irPs, например драйвером контроллера floppy системы, может синхронизировать очередь IRP на семафоре, как показано на предыдущем рисунке:
Поток вызывает KeWaitForSingleObject указателем на хранилище, предоставленное драйвером, для инициализированного объекта семафора, чтобы поместить себя в состояние ожидания.
IrPs начинают поступать, что требуют операций ввода-вывода устройства. Подпрограммы отправки драйвера вставляют каждую из таких операций IRP в заблокированную очередь под элементом управления спин-блокировкой и вызывают KeReleaseSemaphore с указателем на объект семафора, повышение приоритета, определяемого драйвером для потока (добавочного, как показано на предыдущем рисунке), корректировки из 1, добавляемой в число семафора, так как каждый IRP помещается в очередь, и логический wait для FALSE. Ненулевое число семафор задает объект семафора в состояние Signaled, тем самым изменив состояние ожидания потока на готовое.
Ядро отправляет поток для выполнения сразу после того, как процессор доступен: т. е. ни один другой поток с более высоким приоритетом в настоящее время находится в состоянии готовности, и подпрограммы режима ядра не выполняются на более высоком уровне IRQL.
Поток удаляет IRP из межблокировочной очереди под управлением спин-блокировки, передает его другим подпрограммам драйверов для дальнейшей обработки и вызывает KeWaitForSingleObject. Если семафор по-прежнему имеет состояние Signaled (то есть число остается ненулевой, указывая на то, что больше irPs находятся в заблокированной очереди драйвера), ядро снова изменяет состояние потока от ожидания до готовности.
С помощью семафора подсчета таким образом такой поток драйвера "знает", что IRP удаляется из заблокированной очереди при каждом запуске потока.
Сведения об управлении IRQL при вызове KeReleaseSemaphoreсм. в разделе "Замечания" KeReleaseSemaphore.
Любая стандартная подпрограмма драйвера, которая выполняется в IRQL больше PASSIVE_LEVEL не может ожидать ненулевого интервала для любых объектов диспетчера без уменьшения системы; Дополнительные сведения см. в объектах диспетчера ядра. Однако такая подпрограмма может вызывать KeReleaseSemaphore при выполнении в IRQL меньше или равно DISPATCH_LEVEL.
Сводка по irQLs, по которым выполняются стандартные подпрограммы драйверов, см. в разделе Управление приоритетами оборудования. Требования IRQL к определенной подпрограмме поддержки см. на странице справки по подпрограмме.