您的位置:首页 > 其它

C11、线程池的使用

2009-12-08 20:18 85 查看
线程池由四个独立的部分组成:定时器,等待,I/O,非I/O。当进程初始化时,无开销。但是,一旦有线程池函数调用,就为进程创建某些组件。

多线程应用程序的困难,是面对两大问题:管理线程的创建和撤销,资源访问同步。线程池函数的功能:
一、异步调用函数:
a) 该方案是C/S应用程序的典型实现,经常处理异步I/O请求(高性能可伸缩应用程序的秘诀!)
b) 调用函数:
BOOL QueueUserWorkItem(
PTHREAD_START_ROUTINE pfnCallback, // 你的工作函数
PVOID pvContext, // 你的函数传入参数
ULONG dwFalgs); // 你不必调用CreateThread函数!不必为每个客户请求创建和撤销线程。
c) 你的工作函数原型:DWORD WINAPI YourFunc(PVOID pvContext);
d) dwFlags参数说明:
n 非I/O:WT_EXECUTEDEFAULT
n 异步I/O: WT_EXECUTEINIOTHREAD
n 不能终止的线程:WT_EXECUTERPERSISTENTTHREAD
n 长时间运行的项目:WT_EXECUTELONGFUNCTION
e) 注意事项:避免潜在的死锁条件。

二、按规定的时间间隔调用函数(不必为每个基于时间的操作创建一个等待定时器对象):
a) 创建定时器队列:HANDLE CreateTimerQueue();
b) 在队列中创建定时器:
BOOL CreateTimerQueueTimer(
PHANDLE phNewTimer, // 返回的新定时器的句柄
HANDLE hTimerQueue, // 如果只创建少数几个定时器,可用NULL
WAITORTIMERCALLBACK pfnCallback, // 你的工作函数
PVOID pvContext, // 工作函数传入参数
DWORD dwDueTime, // 经过多少ms第一次运行
DWORD dwPeriod, // 间隔多少ms,= 0,则为单步定时器(只运行一次)
ULONG dwFlags);
c) dwFlags参数说明:
n WT_EXECUTEINTIMERTHREAD
n 其他,见上
d) 你的工作函数原型:VOID WINAPI YourFunc(PVOID pvContext, BOOL = TRUE);
e) 删除定时器(即使是单步定时器):
BOOL DeleteTimerQueueTimer(
HANDLE hTimerQueue, // 位于哪个队列
HANDLE hTimer, // 要删除的定时器
HANDLE hCompletionEvent); // 何时不再存在未处理的项目,传入INVALID_HANDLE_VALUE 或 NULL 或 事件内核对象句柄。
f) 改变到期时间和间隔时间:
BOOL ChangeTimerQueueTimer(
HANDLE hTimerUeue,
HANDLE hTimer,
ULONG dwDueTime,
ULONG dwPeriod);
对单步定时器不适用。
g) 服务器终止时,只需删除此队列:
BOOL DeleteTimerQueueEx(
HANDLE hTimerQueue,
HANDLE hCompletionEvent); // 同上

三、当单个内核对象变为已通知状态时调用函数:
a) 调用函数:
BOOL RegisterWaitForSingleObject(
PHANDLE phNewWaitObject, // 返回的句柄,标识等待组件
HANDLE hObject, // 标识内核对象
WATIORTIMERCALLBACK pfnCallback, // 你的工作函数
PVOID pvContext, // 传入你的工作函数的参数
ULONG dwMilliseconds, // 超时,可为0或INFINITE
ULONG dwFlags);
n 负责将参数传送给线程池的等待组件,与WaitForSingleObject相似。
n 不能多次等待单个句柄,如果需要,可用DuplicateHandle复制并分开注册。
a) 你的工作函数原型:VOID WINAPI YourFunc(PVOID pvContex, BOOL); 如果等待超时了,BOOL = TRUE;如变为已通知,BOOL = FALSE。
b) dwFlags参数说明:
n WT_EXECUTEINWAITTHREAD:运行快,有风险(无法等待其他对象得到通知)。只有当工作函数运行得很快时才使用。
n WT_EXECUTEONLYONCE:只执行一次就停止等待该对象。
n 其他,见上
c) 取消等待组件的注册状态:
BOOL UnregisterWaitEx(
HANDLE hWaitHandle, // 由注册函数返回的phNewWaitObject
HANDLE hCompletionEvent); // 同上
n 如无排队的工作项目,返回TRUE,否则FALSE,而GetLastError返回STATUS_PENDING。
d) 注意事项:避免潜在的死锁条件。
e) 在调用UnregisterWaitEx前,不应删除内核对象句柄

四、当异步I/O请求完成时调用函数(常用):
a) 将一个设备与I/O组件关联的函数(I/O组件的线程全部在一个I/O组件端口上等待):
BOOL BindIoCompletionCallback(
HANDLE hDevice,
POVERLAPPED_COMPLETION_ROUTINE pfnCallback,
ULONG dwFlags); // 必须传 0.
b) 你的工作函数原型:
VOID WINAPI OverlappedCompletionRoutine(
DWORD dwErrorCode,
DWORD dwNumberOfBytesTransferred,
POVERLAPPED pOverLapped); // OVERLAPPED结构传递给ReadFile等函数
n 关闭设备会导致他所有待处理的I/O请求立即完成,并产生错误码。所以在回调函数中应处理此情况。避免的方法是使用计数器。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: