方法:
1).通过提高或降低IRQL (只能适用于单CPU).
原理:当IRQL提高到DISPATCH_LEVEL的时候就不会出现线程切换.
注意:提升到DISPATCH_LEVEL的时候程序必须使用非分页内存.原因是分页内容随时都有可能把物理内存中的内容转存到磁盘文件内.读取一个不存在的物理内存中的分页内存会引发页故障 ,而在DISPATCH_LEVEL级以上的级别发生页故障是会引发系统崩溃.
使用: KeGetcurrentIrql 获取当前级别.
KeRaiseIrql提升级别
KeLowerIrql降低级别
2).自旋锁(Spin Lock)
原理:自旋所不同于一般的线程互斥,线程发生自旋锁它不会让cpu切换到别的线程工作.而是一直占用cpu.(在单cpu情况下自旋锁只是通过提升IRQL级别来阻止线程切换就是(1)的方法来实现的;多CPU就比较复杂一定.)
注意:驱动程序必须在<=DISPATCH_LEVEL的IRQL的级别使用自旋锁.
使用: KeAcquireSpinLock
KeReleaseSpinLock
3).KEvent
KEvent 使用 KinitializeEvent, KeWaitForSingleObject,KeWaitFoMultipleObject 实现线程等待.
ObReferenceObjectByHandle(计数+1)实现用户模式的Event转换成内核使用的KEVENT.使用完需要调用ObDereferenceObject(计数-1);
IoCreateNotiticationEvent,IoCreateSynchornizationEvent创建有名的事件打到驱动之间也可以线程等待.达到同步目的.
4) 内核信号灯
使用KeInitializeSemaphore 初始化
KeReadStateSemaphore 获取计数
KeReleaseSemaphore 计数减1
KeWaitForSingleObject 等待.
5)互斥(KNUTEX)
使用 KeinitializeMutex 初始化
KReleaseMutex 释放
KeWaitForSingleObject 等待.
6) 原子锁
InterLockedXXXX实现同步