需要进行延迟处理的驱动程序可以使用 work item,它包含一个驱动回调例程指针,该例程进行实际的操作。驱动将workitem入队,然后系统的工作线程(worker thread)会将workitem出队并执行驱动的回调例程。系统会维护(maintain)用来处理workitem的系统工作线程池(ExpWorkerThread)。
驱动将一个WorkItem回调例程与workitem相关联。当系统工作线程处理 workitem 对象时,它就会调用相关的回调例程。从Windows Vista 版本开始,驱动可以将WorkItemEx例程与workitem相关联来使用。WorkItemEx例程与WorkItem所传入的参数不一样。
WorkItem 和WorkItemEx 在系统线程的上下文执行。如果驱动的分发例程(dispatch routine)可以在用户模式上下文执行,它就可以调用WorkItem或WorkItemEx进行任何需要在系统线程上下文中才能执行的操作。
DPC(延迟过程调用)如果需要发起要求长时间处理(lengthy processing)或会进行阻塞调用(blocking call)的任务时,应该将处理过程委托给一个或多个workitem 去完成。当DPC在运行时,所以线程都被阻止运行。另外,DPC运行在IRQL=DISPATCH_LEVEL,不允许进行阻塞调用。然而,系统工作线程运行在IRQL=PASSIVE_LEVEL,由它处理wrokitem 。因此,workitem可以包含阻塞调用。例如,系统工作线程可以等待分发对象(dispatcher object)。
因为系统工作线程池是有限的资源,WorkItem和WorkItemEx只能被用来进行短时间的操作。如果WorkItem例程运行或等待太长时间,就会造成系统死锁。所以,如果驱动要求长时间的延迟处理,就应该使用PsCreateSystemThread创建属于自己的系统线程。
(从文档里搜集的,加了一点自己的解释)
PIO_WORKITEM IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject);
在这个函数里主要调用ExAllocatePoolWith***去申请一个IO_WORKITEM结构,并对结构体中的一些成员进行初始化。
VOID IoInitializeWorkItem(IN PVOID IoObject,IN PIO_WORKITEM IoWorkItem)
{
if(IoObject->Type==3||IoObject->Type==4)
{
IoWorkItem->WorkItem=0;
IoWorkItem->Type=1;
IoWorkItem->IoObject=IoObject;
IoWorkItem->WorkItem->WorkerRoutine=IopProcessWorkItem;
IoWorkItem->WorkItem-〉Parameter=IoWorkItem;
return ;//可以看出IoWorkItem作为参数传给IopProcessWorkItem去执行
}
KeBugCheckEx(WORKER_INVALID/*0xE4*/,3,IoWorkItem,IoObject,0);
}
VOID IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem,
IN PIO_WORKITEM_ROUTINE WorkerRoutine,
IN WORK_QUEUE_TYPE QueueType,IN PVOID Context);
这个函数将IoWorkItem-〉Type设为0(可能是用来表明这个WorkItem是否如队列),然后调用IoQueueWorkItemEx,它们的参数一样。
IoQueueWorkItemEx(....)
{
ObReferenceObject(IoWorkItem->IoObject);//
IoWorkItem->Comtext-=Context;
ExQueueWorkItem(IoWorkItem,QueueType);
}
WORK_QUEUE_TYPE .QueueType取值为CriticalWorkQueue时,将WorkItem插到会被一个拥有实时(real_time)优先级属性的系统线程处理的队列中;当取值为DelayedWorkQueue时,该WorkItem将会被拥有可变优先级的系统线程处理。
VOID ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem,IN WORK_QUEUE_TYPE QueueType); 这个函数在进行一些信息的核对确保无误后,会调用KiInsertQueue完成入队列操作,之后就是等待被出队,执行吧。
本文详细介绍了Windows驱动程序中WorkItem的使用方法及其内部机制。WorkItem是一种用于执行延迟处理任务的数据结构,通过系统工作线程池处理,允许驱动程序执行阻塞性操作。文章还对比了WorkItem与WorkItemEx的不同之处,并提供了关键API的使用示例。

370

被折叠的 条评论
为什么被折叠?



