windows 内核system worker threads

在编写windows驱动的时候,我们需要关心两个中断级别(IRQL),PASSIVE_LEVEL(0)和DISPATCH_LEVEL(2)。windows大部分的时间,都运行在0-2级别,当设备中断来临时,windows会将IRQL提升至硬件中断级别(DIRQL, DEVICE INTERRUPT REQUEST LEVEL),并且运行相应的硬件中断处理函数。当硬件中断结束后,恢复到原来的IRQL。
用户模式的代码是运行在最低级别的PASSIVE_LEVEL中,驱动程序的DriverEntry函数,派遣函数,AddDevice函数一般运行在PASSIVE_LEVEL中(驱动程序的StartIO和DPC函数运行在DISPATCH_LEVEL中),它们在必要的时候可以申请进入DISPATCH_LEVEL级别,使用内核函数KeGetCurrentIrql()可以知道系统的当前IRQL。

Windows负责线程调度的组件运行在DISPATCH_LEVEL级别,当前线程运行完时间片后,操作系统自动从PASSIVE_LEVEL提升至DISPATCH_LEVEL级别,从而可以使得线程调度组件可以调度其他的线程。当线程切换完成后,操作系统又从DISPATCH_LEVEL级别恢复到PASSIVE_LEVEL级别。

有时候,锁会提升程序的IRQL。比如说从0(PASSIVE_LEVEL)提升到了DISPATCH_LEVEL中,这就会导致有的api使用不了

使用system worker threads可以解决这个问题

WorkItem能排队注册的回调函数, 当例程处于DISPATCH_LEVEL(2)级别时将回调函数塞入队列,当进程降低到PASSIVE_LEVEL(0)时,这些队列中的回调函数将会被系统调用。
注意事项:
而且根据CSDN的介绍,工作队列有两个需要注意的地方。一是不能执行太长的操作,会死锁。2是在排队工作项之前,最好释放所有的mutex、lock、semaphore,否则很容易死锁。
反正这两种操作都不错(另一种线程的方法参见前面文档)。随便选一个用用就行了。

官方文档

https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/system-worker-threads

大概翻译:
当你需要driver延迟执行某些动作的时候,可以使用work item。driver可以把这些work item入队。windows系统维护了一个线程池,线程会从队列中取出来一个work item,并执行他的回掉routine, 并且从队列中删除它。

To use a work item, a driver performs the following steps:

  1. Allocate and initialize a new work item.(IoAllocateWorkItem)
    2.关联一个回掉历程。([IoQueueWorkItem])
  2. 释放。( IoFreeWorkItem

代码片段

PIO_WORKITEM pIoWorkItem;
pIoWorkItem = IoAllocateWorkItem(device);
if (pIoWorkItem)
        {
            IoQueueWorkItem(pIoWorkItem, CallBack, DelayedWorkQueue, NULL);
            IoFreeWorkItem(pIoWorkItem);
        }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,161评论 1 32
  • 1.NSTimer不准时的原因:(1).RunLoop循环处理时间,每次循环是固定时间,只有在这段时间才会去查看N...
    稻春阅读 1,291评论 0 3
  • Execute code concurrently on multicore hardware by submit...
    ngugg阅读 638评论 0 1
  • 一:base.h 二:block.h 1. dispatch_block_flags:DISPATCH_BLOCK...
    小暖风阅读 2,524评论 0 0
  • __block和__weak修饰符的区别其实是挺明显的:1.__block不管是ARC还是MRC模式下都可以使用,...
    LZM轮回阅读 3,407评论 0 6