同步和线程 DPC
若要同步对 从 CustomThreadedDpc 例程内部和外部访问的内存位置的访问,驱动程序可以使用普通的旋转锁或排队的旋转锁。 执行此操作时,驱动程序必须遵循某些规则才能在 IRQL = PASSIVE_LEVEL 和 IRQL = DISPATCH_LEVEL 正确同步,因为 CustomThreadedDpc 例程可以在两个 IRQL 中执行。
对于普通旋转锁,以下规则适用:
若要获取并释放旋转锁,驱动程序可以从 CustomThreadedDpc 例程内外调用 KeAcquireSpinLock 和 KeReleaseSpinLock。
驱动程序可以从 CustomThreadedDpc 例程内部调用 KeAcquireSpinLockForDpc 和 KeReleaseSpinLockForDpc。 请注意, CustomThreadedDpc 例程不得调用 KeAcquireSpinLockAtDpcLevel 或 KeReleaseSpinLockFromDpcLevel,因为这些例程只能安全地调用 IRQL = DISPATCH_LEVEL。
排队旋转锁的规则类似:
若要获取并释放旋转锁,驱动程序可以从 CustomThreadedDpc 例程内外调用 KeAcquireInStackQueuedSpinLock 和 KeReleaseInStackQueuedSpinLock。
驱动程序可以从 CustomThreadedDpc 例程内部调用 KeAcquireInStackQueuedSpinLockForDpc 和 KeReleaseInStackQueuedSpinLockForDpc。 请注意, CustomThreadedDpc 例程不得调用 KeAcquireInStackQueuedSpinLockAtDpcLevel 或 KeReleaseInStackQueuedSpinLockFromDpcLevel,因为这些例程只能安全地调用 IRQL = DISPATCH_LEVEL。
由于 KeAcquireSpinLockForDpc 和 KeAcquireInStackQueuedSpinLockForDpc 在 DISPATCH_LEVEL 调用时不会重置 IRQL,因此它们的执行速度分别比 KeAcquireSpinLock 和 KeAcquireInStackQueuedSpinLock 更快。
有关旋转锁的详细信息,请参阅旋转锁。