スレッド DPC の概要
スレッド DPC は、Windows Vista、およびそれ以降のバージョンの Windows で使用することができます。
スレッド DPC は、システムが IRQL で実行する DPC であり、PASSIVE_LEVEL と同等です。 スレッド DPC は既定で有効になっていますが、HKLM\System\CCS\Control\SessionManager\Kernel\ThreadDpcEnable レジストリ キーを 0 に設定することで無効にすることができます。 スレッド DPC を無効にすると、通常の DPC として実行されます。
通常の DPC では、すべてのスレッドの実行が優先され、スレッドまたは別の DPC による割り込みはできません。 システムに多数の通常の DPC がキューに入っている場合、またはそれらの DPC の 1 つが長時間実行されている場合、すべてのスレッドは任意の長い時間、一時停止したままになります。 したがって、通常の DPC ごとにシステム待機時間が長くなり、オーディオやビデオの再生など、時間の影響を受けやすいアプリケーションのパフォーマンスが低下する可能性があります。
逆に、スレッド化された DPC は通常の DPC による割り込みは可能ですが、他のスレッドによる割り込みはできません。 そのため、特定の DPC が別の DPC によっても割り込まれないようにする必要がある場合を除いて、通常の DPC ではなくスレッド DPC を使用する必要があります。
このシステムは、スレッド化された DPC (および通常の DPC) を KDPC 構造体として表します。 スレッド化された DPC の KDPC 構造体を初期化するには、KeInitializeThreadedDpc ルーチンを呼び出し、DPC のアクションを実行する CustomThreadedDpc ルーチンを渡します。
CustomThreadedDpc ルーチンは PASSIVE_LEVEL または DISPATCH_LEVEL で実行できるため、CustomThreadedDpc ルーチンが両方の IRQL で正しく同期されるようにする必要があります。 その方法の詳細については、「同期とスレッド 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 を呼び出します。