《Windows核心编程》之“线程池”

来源:互联网 发布:android 崩溃数据丢失 编辑:程序博客网 时间:2024/05/23 02:05

    本文主要结合四个应用场景介绍Windows内置的几种线程池机制,并配了一张思维导图。事实上,Jeffrey在该书中,并没有过深的去探讨“线程池”的机制,Windows所提供的这四种线程池机制也并非所有场景都合适,后续我将会单独开一篇博客来自己实现一个线程池。


    如上图,本文主要介绍这四个线程池应用场景。

一、异步函数调用

    它的流程大致分为三步,参考batch.exe示例。

1)定义回调例程——TaskHandler;

2)创建工作项。

   // Create the work item that will be used by all tasks   g_pWorkItem = CreateThreadpoolWork(TaskHandler, NULL, NULL);

3)提交任务。

   // Submit 4 tasks by using the same work item   SubmitThreadpoolWork(g_pWorkItem);   SubmitThreadpoolWork(g_pWorkItem);   SubmitThreadpoolWork(g_pWorkItem);   SubmitThreadpoolWork(g_pWorkItem);

    仅此而已,任务提交后,系统会自动将它分配给线程池中的线程去“执行”。所谓的“执行”,就是调用回调例程。


二、定时器

    Jeffrey介绍的第二种应用场景,实际上就是定时器。我们可以直接用“waitable timer”,也可以用该章介绍的便利函数。事实上,QT的Timer封装的更好,使用起来更方便。

    参照TimedMsgBox.exe示例,它的流程如下:

1)定义回调例程——MsgBoxTimeoutCallback。

2)创建Timer

   // Create the threadpool timer object   PTP_TIMER lpTimer =       CreateThreadpoolTimer(MsgBoxTimeoutCallback, NULL, NULL);

3)启动Timer

   // Start the timer in one second to trigger every 1 second   ULARGE_INTEGER ulRelativeStartTime;   ulRelativeStartTime.QuadPart = (LONGLONG) -(10000000);  // start in 1 second   FILETIME ftRelativeStartTime;   ftRelativeStartTime.dwHighDateTime = ulRelativeStartTime.HighPart;   ftRelativeStartTime.dwLowDateTime  = ulRelativeStartTime.LowPart;   SetThreadpoolTimer(      lpTimer,       &ftRelativeStartTime,       1000, // Triggers every 1000 milliseconds      0      );

    仅此而已,系统会周期性的调用回调例程。


三、内核触发

    “等待某个内核对象触发,然后执行异步调用”,相对前面两题,这是更一般意义的机制。它的步骤如下:

1)定义回调例程;

2) 创建线程池等待对象;

PTP_WAIT CreateThreadpoolWait(    PTP_WAIT_CALLBACK    pfnWaitCallback,PVOID                pvContext,PTP_CALLBACK_ENVIRON pcbe);

3)绑定线程池等待对象与被等待内核对象

VOID SetThreadpoolWait(    PTP_WAIT    pWaitItem,HANDLE      hObjcet,PFILETIME   pftTimeout);


四、异步IO完成通知

    最后一种常见是等待异步IO完成通知,然后调用异步执行函数。步骤如下:

1)定义回调函数,包含重叠结构。

2)创建一个线程池IO对象

PTP_WAIT CreateThreadpoolIo(    HANDLE                   hDevice,    PTP_WIN32_IO_CALLBACK    pfnWaitCallback,PVOID                    pvContext,PTP_CALLBACK_ENVIRON     pcbe);


3)关联设备对象和线程池IO对象

VOID StartThreadpoolIo(PTP_IO pio);


0 0