Поделиться через


Введение в потоковые DPC

Потоковые DPC доступны в Windows Vista и более поздних версиях Windows.

Поток DPC — это DPC, который система выполняет в IRQL, равном PASSIVE_LEVEL. Потоковые DPC включены по умолчанию, но их можно отключить, задав для раздела реестра HKLM\System\CCS\Control\SessionManager\Kernel\ThreadDpcEnable значение 0. Если потоковые DPC отключены, они выполняются как обычные DPC.

Обычный DPC вытесняет выполнение всех потоков и не может быть вытеснен потоком или другим DPC. Если в системе есть большое количество обычных DPC, помещенных в очередь, или если один из них работает в течение длительного времени, каждый поток будет оставаться приостановленным в течение произвольно длительного времени. Таким образом, каждый обычный DPC увеличивает системную задержку, что может повредить производительности приложений, чувствительных к времени, таких как воспроизведение звука или видео.

И наоборот, поток DPC может быть вытеснен обычным DPC, но не другими потоками. Поэтому следует использовать потоковые DPC, а не обычные DPC, если только конкретный DPC не должен быть вытеснен, даже другим DPC.

Система представляет потоковые DPC (и обычные DPC) как структуры KDPC . Чтобы инициализировать структуру KDPC для потока DPC, вызовите подпрограмму KeInitializeThreadedDpc и передайте ей подпрограмму CustomThreadedDpc , которая выполняет действие DPC.

Так как подпрограмма CustomThreadedDpc может выполняться в PASSIVE_LEVEL или DISPATCH_LEVEL, необходимо убедиться, что подпрограмма CustomThreadedDpc правильно синхронизируется в обоих списках IRQ. Дополнительные сведения о том, как это сделать, см. в разделе Синхронизация и потоковые DPC.

Кроме того, необходимо убедиться, что подпрограмма CustomThreadedDpc подчиняется всем ограничениям для DISPATCH_LEVEL кода. Если потоковые DPC включены, они выполняются в IRQL = PASSIVE_LEVEL но по-прежнему распространяются те же ограничения, что и обычные DPC. Весь код, выполняемый в потоковом DPC, включая все функции, вызываемые подпрограммой CustomThreadedDpc , должен соответствовать ограничениям среды DPC. Например, код не должен блокировать объекты синхронизации пассивного уровня, такие как объекты KEVENT. Многие существующие стеки устройств, такие как сеть и USB, не поддерживают потоковую обработку DPC и могут попытаться заблокировать, если обнаруживают, что они вызываются на PASSIVE_LEVEL. По аналогичным причинам платформа драйвера режима ядра (KMDF) не поддерживает потоковую обработку DPC, и драйверы KMDF не должны пытаться использовать потоковые DPC. Дополнительные сведения о среде DPC см. в разделе Написание процедур DPC.

Чтобы добавить поток DPC в очередь DPC, вызовите KeInsertQueueDpc. Чтобы удалить поток DPC из очереди перед его выполнением, вызовите KeRemoveQueueDpc.