线程池函数允许我们做:
1.以异步方式调用函数 //工作项
2.每隔一段时间调用一个函数 //计时项
3.在内核对象触发时调用一个函数 //等待项
4.在异步I/O请求完成时调用一个函数 //I/O项
2.每隔一段时间调用一个函数
如果两个:周期的每隔5-7秒执行一段代码,周期的每隔6-8秒执行一段代码。
不用线程池将有两个线程执行,上下文切换不好,如用线程池,系统可能选择6秒间隔只唤醒一个线程执行这两段代码。
3.在内核对象触发时调用一个函数
同上类似,各个线程WaitForSingleObject各自的内核对象,如用线程池用一个线程WaitForMultipleObjects 最多MAXIMUM_WAIT_OBJECTS个内核对象
一旦回调函数被调用过,必须SetThreadpoolWait再注册下,否则 等待项 是不活跃状态不会再调用回调函数
#include <Windows.h>
// C RunTime Header Files
#include <string>
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);
wprintf(L"[%u] Task #%u is starting.\n", GetCurrentThreadId(), currentTask);
// Simulate a lot of work
Sleep(currentTask * 1000);
wprintf(L"[%u] Task #%u is done.\n", GetCurrentThreadId(), currentTask);
InterlockedDecrement(&g_nCurrentTask);
}
void Work(void)
{
// Create the work item that will be used by all tasks
//(1)create 线程池工作项
g_pWorkItem = CreateThreadpoolWork(TaskHandler, NULL, NULL);
if (g_pWorkItem == NULL) {
wprintf(L"Impossible to create the work item for tasks.\n");
return;
}
wprintf(L"----Start a new batch----\n");
for(int i = 4; i > 0; --i)
{
//(2)submit work
SubmitThreadpoolWork(g_pWorkItem);
}
wprintf(L"4 tasks are submitted.\n");
//Waits for outstanding work callbacks to complete and optionally cancels pending callbacks that have not yet started to execute.
//(3)wait for work over
WaitForThreadpoolWorkCallbacks(g_pWorkItem,FALSE);
// Don't forget to delete the work item
//(4)delete work item
CloseThreadpoolWork(g_pWorkItem);
}
PTP_TIMER g_timer = NULL;
volatile LONG g_nSecLeft = 10;
VOID CALLBACK TimeoutCallback(PTP_CALLBACK_INSTANCE pInst, PVOID pvContext, PTP_TIMER pTimer)
{
LONG current = InterlockedDecrement(&g_nSecLeft);
if(current == 0)
{
SetThreadpoolTimer(g_timer,NULL,0,0); //pftDueTime为NULL时,将停止调用定时器函数
wprintf(L"time out----\n");
}
else
{
wprintf(L"[%u] call timer callback function #%u is left.\n", GetCurrentThreadId(), current);
}
}
void Timer(void)
{
g_timer = CreateThreadpoolTimer(TimeoutCallback,NULL,NULL);
// Start the timer in one second to trigger every 1 second
ULARGE_INTEGER ulRelativeStartTime;
ulRelativeStartTime.QuadPart = (LONGLONG) -1; // start now
FILETIME ftRelativeStartTime;
ftRelativeStartTime.dwHighDateTime = ulRelativeStartTime.HighPart;
ftRelativeStartTime.dwLowDateTime = ulRelativeStartTime.LowPart;
SetThreadpoolTimer(
g_timer,
&ftRelativeStartTime,
1000, // Triggers every 1000 milliseconds
INFINITE//0
);
//WaitForThreadpoolTimerCallbacks(g_timer,FALSE); //Why this will fail?
getchar();
CloseThreadpoolTimer(g_timer);
}
VOID NTAPI pttwaitcallback(
_Inout_ PTP_CALLBACK_INSTANCE Instance,
_Inout_opt_ PVOID Context,
_Inout_ PTP_WAIT Wait,
_In_ TP_WAIT_RESULT WaitResult
)
{
wprintf(L"waitResult is WAIT_OBJECT_0 + %d.\n",WaitResult);
}
void WaitKernelObject()
{
PTP_WAIT pwait = CreateThreadpoolWait(pttwaitcallback,NULL,NULL);
HANDLE hEvent1 = CreateEventW(NULL,FALSE,FALSE,L"event1");
HANDLE hEvent2 = CreateEventW(NULL,FALSE,FALSE,L"event2");
SetThreadpoolWait(pwait,hEvent1,NULL);
SetEvent(hEvent1); //here will make pwait 不活跃状态, 此状态不会再去调回调函数。
getchar();
SetThreadpoolWait(pwait,hEvent2,NULL); //不活跃状态后需要重新设置
SetEvent(hEvent2);
//WaitForThreadpoolWaitCallbacks(pwait,FALSE);
getchar();
CloseThreadpoolWait(pwait);
}
int wmain()
{
//Work();
Timer();
//WaitKernelObject();
wprintf(L"it is over\n");
getchar();
return(0);
}