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;
}
運行結果如圖: