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;
}

運行結果如圖:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章