内核驱动程序的同步处理、线程保护

在支持多线程的操作系统下,有些函数会出现不可重入的现象。所谓“可重入”,是指函数的执行结果不和执行顺序有关。反之则称这个函数是“不可重入”的。

经常出行不可重入现象的情况是因为代码和全局变量有关,多个线程“同时”运行时,可能会导致汇编指令交错在一起。所以最终的全局变量的值是可能不一样的。

本篇文章只是为了复习回顾用,以下介绍到的API不甚详细,具体的API参数和调用参考MSDN

1.中断请求级

Windows将中断请求划分为软件中断和硬件中断,并将这些中断都映射成不同级别的中断请求级(IRQL).同步处理机制很大程度上依赖于中断请求级

驱动程序使用内核函数KeRaiseIrql将IRQL提高,KeRaiseIrql需要两个参数,第一个参数是提升后的IRQL级别,第二个参数保存提升前的IRQL级别。

2.自旋锁

所谓自旋状态,即是不停地询问是否可以“获得”这个锁, 所以需要资源的进程并不会释放CPU,反而因为一直询问会一直存在于CPU轮询队列中,浪费CPU宝贵的时间。所以对于处理等待时间长的资源,自旋锁并不合适。而在内核中,因为内核的进程操作一般比较简单,所以等待时间不会太长,因此内核编程在处理线程同步的时候,自旋锁技术是非常常见的技术。但是需要注意的是。驱动程序必须在低于或者等于DISPATCH_LEVEL的IRQL级别中使用自旋锁。

使用自旋锁,需要对其初始化,可以使用KeInitializeSpinLock内核函数。一般在驱动程序中的DriverEntry或者AddDevice函数中初始化自旋锁。

释放自旋锁使用KeReleaseSpinLock内核函数,它也是两个参数,第一个为自旋锁指针,第二个是释放自旋锁后应该恢复的IRQL级别。

获得自旋锁的内核函数是KeAcquireSpinLock。直到自旋锁被释放后,另外的程序才能获得到自旋锁。

3内核模式下的同步对象

内核模式下的等待

在内核模式下,KeWaitForSingleObject和KeWaitForMultipleObjects函数负责等待内核同步对象。

内核模式下开启多线程

内核函数PsCreateSystemThread负责创建新线程。该函数可以创建两种线程,一种是用户线程,一种是系统线程。

内核模式下的事件对象

在内核中,用KEVENT数据结构表示一个事件对象。内核函数KeInitializeEvent负责对事件对象初始化

内核模式下的油槽(信号灯)

使用内核函数KeInitializeSemaphore对信号灯对象进行初始化

内核模式下的互斥体

KeInitializeMutex内核函数初始化互斥体对象 KeReleaseMutex内核函数释放互斥体

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(windows内核编程,驱动,内核)