Windows提供了線程池機制,可以直接調用相關API使用。
先介紹一種最簡單的線程池API的使用。
1、TrySubmitThreadpoolCallback
TrySubmitThreadCallback函數是向線程池提交一個請求,請求讓線程池中的線程執行某個函數。該函數的函數原型如下所示:
BOOL TrySubmitThreadpoolCallback(
PTP_SIMPLE_CALLBACK pfnCallBack, //請求調用的回調函數
PVOID pvContext, //向回調函數傳遞的參數
PTP_CALLBACK_ENVIRON pcbe //可以通過該參數定製線程池,一般置爲NULL
);
其中pfnCallBack必須是滿足一下原型的函數
VOID NTAPI SimpleCallback(
PTP_CALLBACK_INSTANCE pInstance,
PVOID pvContext //傳遞的參數
);
實例如下所示:
#include <Windows.h> //Must be included
#include <map>
using namespace std;
map<DWORD, DWORD> g_map;
DWORD g_CurrentTask = 0;
void NTAPI SimpleCallBack(PTP_CALLBACK_INSTANCE pInstance, PVOID pvContext)
{
int k = *(int *)pvContext;
//printf(">>> k: %d\n", k);
InterlockedIncrement(&g_CurrentTask); //自動遞增全局任務計數器,以原子量的方式實現
DWORD threadID = GetCurrentThreadId(); //獲取當前任務的線程ID號
g_map[threadID] = g_CurrentTask;
printf(">>> 【%d】- %d 線程開始運行!\n", threadID, g_CurrentTask);
Sleep(g_CurrentTask * 1000); //Do Something ...
printf(">>> 線程 %d 執行完畢!\n", g_map[GetCurrentThreadId()]);
if( InterlockedDecrement(&g_CurrentTask) == 0 ) //當該任務執行完畢後,就自動遞減全局任務計數器
{
printf(">>> 所有線程均已執行完畢!\n");
}
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
// 向線程池提交申請
int i = 0;
for(i = 0; i < 10; i++)
{
Sleep(10);
//BOOL rBet = TrySubmitThreadpoolCallback(SimpleCallBack, NULL, NULL);
BOOL rBet = TrySubmitThreadpoolCallback(SimpleCallBack, (PVOID)&i, NULL);
if(!rBet)
{
printf(">>> ERROR: 向線程池提交申請失敗!\n");
}
else
{
//printf(">>> 向線程池提交申請成功!\n");
}
}
getchar();
return 0;
}
程序執行結果如下所示:
2、