Windows核心编程<读书笔记十一>线程池的使用

线程池的使用

【文起】已经和蟹儿在一起了,谢谢宝贝儿的支持和鼓励。最近工作比较忙,耽搁了上传笔记

1、 多线程应用程序是非常困难的。面临两个大问题:

1.1 要对线程的创建和撤销进行管理;

1.2 要对线程对资源的访问实施同步。

如何让系统自动保护共享资源呢?我们可以通过线程池的方式来实现

2、 线程池:

2.1 异步调用函数;

2.2 按照规定的时间间隔调用函数;

2.3 当单个内核对象变为已通知状态时调用函数;

2.4 当异步I/O 请求完成时调用函数

3、 异步调用函数:

   客户机/服务器的实现方法:一个主线专门用来等待客户机请求,收到请求之后产生一个专门的线程用来处理该请求。

         服务器进程收到客户机的请求时,可以调用函数

BOOLQueueUserWorkItem(PTHREAD_START_ROUTINE pfnCallback,PVOID pvContext,ULONG dwFlags);该函数将一个WorkItem放入线程池中的一个线程中,并立即返回。WorkItem是指pfnCallback函数。其原型必须是

DWORDWINAPI WorkItemFunc(PVOID pvContext);

我们不需要调用CreateThread,系统会自动为进程创建一个线程池,线程池中的一个线程将调用函数。该线程处理完客户机的请求后,线程并不立即被撤销,它要返回线程池,这样可以继续处理已经排队的其他工作项目。

I/O组件必须放入线程池中的I/O组件中进行排队。如果需要放入非I/O组件中排队,可以给dwFlags参数传递WT_EXECUTEINIOTHREAD

Windows提供一些函数,可以异步执行与非I/O相关的任务。如RegNotifyChangeKeyValue

我们可以通过给dwFlags参数传入WT_EXECUTELONFUNCTION标志,这样进程池将会自己决定是否要添加新线程。

如果工作项目函数位于可能被动态卸载的DLL中,需求注意不能调用已卸载的DLL。可以在调用QueueUserWorkItem函数之前递增计数器的值,当工作项目函数完成时则递减该计数器的值。只有引用计数将为0时,才能安全卸载DLL。

4、 按规定的时间间隔调用函数:

使用HANDLE CreateTimerQueue()创建一个定时器队列。然后在该定时器队列中创建定时

器 BOOL CreateTimerQueueTimer(PHANDLE phNewTimer,HANDLEhTimerQueue,WAITORTIMERCALLBACK pfnCallback,PVOID pvContext,DWORDdwDueTime,DWORD dwPeriod,ULONG dwFlags);

第二个参数,可以传递定时器队列句柄,如果传入NULL,则使用默认的定时器队列。

删除触发定时器:BOOL DeleteTimerQueueTimer()

修改定时器参数:BOOL ChangeTimerQueueTimer(),此函数不必担心死锁

 

5、  单个内核对象变为已通知状态时调用函数

可以使用函数 BOOL RegisterWaitForSingleObject(PHANDLEphNewWaitObject,

HANDLE hObject,WAITORTIMERCALLBACK pfnCallback,PVOID  pvContext,

ULONG  dwMilliseconds,  ULONG dwFlags);

工作项目准备执行时,被默认排队放入非I/O组件的线程中,这些线程之一最终会醒来,且调用自己写的处理函数,原型必须为

VOID WINAPI WaitOrTimerCallBackFunc(PVOID pvContext,BOOLEANfTimerOrWaitFired);

如果等待超时,fTimerOrWaitFired参数的值是TRUE,如果等待时对象变为已通知状态,则该参数为FALSE

取消等待组件的注册状态:

BOOL  UnregisterWaitEx(HANDLE  hWaitHandle, HANDLE  hCompletionEvent);

第一个参数指明一个注册的等待,第二参数指明当已注册的、正在等待的所有已排队的工作项目已经执行时,希望如何通知你。

6、 当异步I/O请求完成运行时,调用函数

服务器应用程序发出某些异步I/O请求,当这些请求完成时,需要让一个线程池准备好来处理已完成的I/O请求。

将设备与该组件关联起来,可以调用如下函数:

BOOL  BindIoCompletionCallback(HANDLE hDevice,  POVERLAPPED_COMPLETION_ROUTINE  pfnCallback, ULONG dwFlags);

这样该设备的I/O运行完成时,非I/O组件就知道要调用哪个函数,以便能够处理已完成的I/O请求。

关闭设备会导致它所有有待处理的I/O请求立即完成,并产生一个错误码,所以尽量如此处理:1、每次发出一个I/O请求,必须使计数器递增1;2、每次完成一个I/0请求,必须递减计数器。

 【文尾】爱蟹儿,爱生活

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值