Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Ядро определяет набор типов объектов, называемых объектами диспетчера ядра или просто объектами диспетчера. Объекты диспетчера включают объекты таймера, объекты событий, объекты семафора, объекты мьютекса и объекты потоков.
Драйверы могут использовать объекты диспетчера как механизмы синхронизации в определённом контексте потока при выполнении на IRQL, равном PASSIVE_LEVEL.
Состояния объектов диспетчера
Каждый тип объекта диспетчера, определяемого ядром, может находиться в состоянии Signaled или Not-Signaled.
Группа потоков может синхронизировать свои операции, если один или несколько потоков вызывают KeWaitForSingleObject, KeWaitForMutexObject или KeWaitForMultipleObjects. Эти функции принимают указатели объектов диспетчера в качестве входных данных и ожидают, пока другая подпрограмма или поток устанавливает один или несколько объектов диспетчера в состояние Signaled.
Когда поток вызывает KeWaitForSingleObject, чтобы ожидать объект диспетчера (или KeWaitForMutexObject в случае мьютекса), поток переводится в состояние ожидания, пока объект диспетчера не будет установлен в состояние "Сигнал". Поток может вызывать KeWaitForMultipleObjects, чтобы дождаться, когда хотя бы один или все объекты диспетчера будут переведены в состояние Signaled.
Всякий раз, когда объект диспетчера имеет состояние Signaled, ядро изменяет состояние любого потока, ожидающего готовности этого объекта. (Таймеры синхронизации и события синхронизации являются исключениями из этого правила; при сигнале события синхронизации или таймера только один ожидающий поток переводится в состояние готовности. Дополнительные сведения см. в разделах Объекты таймера и DPC и Объекты событий.) Поток в состоянии готовности будет планироваться на выполнение в соответствии с текущим приоритетом потока времени выполнения и текущей доступностью процессоров для любого потока с таким приоритетом.
Когда водители могут ожидать объектов диспетчера?
Как правило, водители могут ожидать установки объектов диспетчера, только если по крайней мере одно из следующих обстоятельств является истинным:
Драйвер выполняется в контексте непарбитрарного потока.
Вы можете определить поток, который войдет в состояние ожидания. На практике единственными подпрограммами драйверов, которые выполняются в контексте неарбитрарного потока, являются DriverEntry, AddDevice, Reinitialize и выгрузка подпрограмм любого драйвера, а также подпрограммы отправки драйверов высокого уровня. Все эти подпрограммы вызываются непосредственно системой.
Драйвер выполняет полностью синхронный запрос ввода-вывода.
То есть при обработке запроса ввода-вывода драйвер не выполняет никаких операций, а драйвер не возвращается до тех пор, пока драйвер под ним не завершит обработку запроса.
Кроме того, драйвер не может войти в состояние ожидания, если он выполняется на уровне IRQL, равном DISPATCH_LEVEL или выше.
В зависимости от этих ограничений необходимо использовать следующие правила:
Подпрограммы DriverEntry, AddDevice, Reinitialize и Unload любого драйвера могут ожидать объектов диспетчера.
Подпрограммы отправки высокоуровневого драйвера могут ожидать завершения объектов диспетчера.
Подпрограммы отправки драйверов нижнего уровня могут ждать объектов диспетчеризации, если операция ввода-вывода синхронна, например операции создания, очистки, завершения работы и закрытия объектов, некоторые операции управления устройством ввода-вывода, а также некоторые операции управления PnP и питанием.
Подпрограммы обработки в драйверах нижнего уровня не могут ожидать завершения асинхронных операций ввода-вывода с использованием объекта диспетчера.
Подпрограмма драйвера, выполняемая на уровне IRQL DISPATCH_LEVEL или выше, не должна ожидать, пока объект диспетчера перейдет в сигнальное состояние.
Драйвер не должен пытаться ждать, чтобы объект диспетчера был установлен в состояние Сигнализирующее для завершения операции передачи на перегружающее устройство или с него.
Подпрограммы диспетчеризации драйверов, обслуживающие запросы на чтение и запись, обычно не могут ждать установки объекта диспетчера в состояние сигнализации.
Диспетчерская процедура для запроса управления вводом-выводом устройства может ожидать, пока диспетчерский объект не перейдёт в состояние Signal, только если тип передачи для кода управления вводом-выводом — METHOD_BUFFERED.
Драйверы мини-порта SCSI не должны использовать объекты диспетчера ядра. Драйверы мини-порта SCSI должны вызывать только подпрограммы поддержки драйверов портов SCSI.
Каждая вторая стандартная подпрограмма драйвера выполняется в произвольном контексте потока: в контексте текущего потока, когда подпрограмма драйвера вызывается для обработки операции в очереди или для обработки прерывания устройства. Кроме того, большинство стандартных подпрограмм драйверов выполняются на повышенном уровне IRQL, либо на DISPATCH_LEVEL, либо, для драйверов устройств, на DIRQL.
При необходимости драйвер может создать выделенный для устройства поток, который может ожидать выполнения других подпрограмм драйвера (за исключением подпрограммы ISR или SynchCritSection ), чтобы задать объект диспетчера в состояние Signaled и сбросить его в состояние Not-Signaled.
В качестве общего руководства, если вы ожидаете, что новый драйвер устройства часто должен застопориться дольше 50 микросекунд, пока он ожидает изменения состояния устройства во время операций ввода-вывода, рассмотрите возможность реализации драйвера с выделенным потоком устройства. Если драйвер устройства также является драйвером высокого уровня, рассмотрите возможность использования системных рабочих потоков и реализации одной или нескольких подпрограмм обратного вызова рабочих потоков. См. PsCreateSystemThread и управление межблокируемыми очередями с помощью созданного драйвером потока.