Windows核心编程--线程池异步调用
Windows线程池函数允许我们做以下事情:
1、以异步方式来调用一个函数;
2、每隔一段时间调用一个函数;
3、当内核对象触发的时候调用一个函数;
4、当异步I/O请求完成的时候调用一个函数。
对于线程池,我们从来不需要调用CreateThead函数,系统会为我们自动创建一个默认的线程池,并让线程池中的一个线程来调用我们的回调函数。此外线程处理完一个客户请求之后,它不会被立刻销毁,而是会回到线程池,准备处理队列中的任何其他工作项。线程池会不断重复使用其中的线程,而不会频繁地创建和销毁线程。如果系统检测到线程池检测它的线程数量已经供过于求,它会销毁其中一些线程。
PTP_WORK CreateThreadpoolWork(
PTP_WORK_CALLBACK pfnWorkHandler,
PVOID pvContext,
PTP_CALLBACK_ENVIRON pcbe
);
该函数可以用来创建一个工作项。
pfnWorkHandler:函数指针;
pvContext: 传给回调函数的任意值;
VOID SubmitThreadpoolWork( PTP_WORK pWork);
需要向线程池提交y一个请求的时候,可调用SubmitThreadpoolWork函数,pWork是我们通过CreateThreadpoolWork函数创建的工作项。
VOID WaitForThreadpoolWorkCallbacks( PTP_WORK pWork, BOOL bCancelPendingCallbacks );
pWork是我们之前创建的工作项,bCancelPendingCallbacks 如果为true,那么当当前工作项执行结束就返回,当为false的时候,需要等待线程池中所有工作项完成之后再返回。
VOID CloseThreadpoolWork( PTP_WORK pWork)
不再需要一个工作项的时,调用该函数结束该工作项。
下面是代码demo:
//Thread
pool
PTP_WORK g_pWorkItem = NULL;
volatile LONG g_nCurrentTask = 0;
VOID NTAPI TaskHandler(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work)
{
LONG currentTask = InterlockedIncrement(&g_nCurrentTask);
TCHAR szMsg[MAX_PATH];
StringCchPrintf(szMsg, _countof(szMsg), _T("[%u]Task #%u is starting."), GetCurrentThreadId(), currentTask);
_tprintf(_T("[szMsg start]%s\n"), szMsg);
Sleep(currentTask * 1000);
StringCchPrintf(szMsg, _countof(szMsg), _T("[%u]Task #%u is done."), GetCurrentThreadId(), currentTask);
_tprintf(_T("[szMsg done]%s\n"), szMsg);
if (InterlockedDecrement(&g_nCurrentTask) == 0)
{
_tprintf(_T("All Task is END\n"));
}
}
//end
int
_tmain( int argc, TCHAR* argv[] )
{
//thread pool
g_pWorkItem = CreateThreadpoolWork(TaskHandler, NULL, NULL);
if (NULL == g_pWorkItem )
{
_tprintf(_T("Impossible to create the work item fot tasks\n"));
return -1;
}
//Submit 3 tasks by using the same work item
SubmitThreadpoolWork(g_pWorkItem);
SubmitThreadpoolWork(g_pWorkItem);
SubmitThreadpoolWork(g_pWorkItem);
_tprintf(_T(" 3 tasks are submitted to thread pool\n"));
WaitForThreadpoolWorkCallbacks(g_pWorkItem, FALSE);
CloseThreadpoolWork(g_pWorkItem);
return
0;
}
运行结果如图: