Windows核心编程--线程池定时器

Windows提供了可等待的计时器内核对象,它使我们非常容易的得到一个基于时间的通知。创建一个可等待计时器内核对象会浪费系统资源。利用线程池来处理定时任务再合适不过了。

PTP_TIMER CreateThreadpoolTimer(

PTP_TIMER_CALLBACK pfnTimerCallback,

PVOID pvContext,

PTP_CALLBACK_ENVIRON pcbe);

与创建工作项函数CreateThreadpoolWork相似。pfnTimerCaizhllback必须是以下函数的原型。

VOID CALLBACK TimeoutCallback(

PTP_CALLBACK_INSTANCE pInstance,

PVOID pvContext,

PTP_TIMER pTimer);

pvContext是pfnTimerCallback的参数,可以为NULL,pTimer参数中传入一个计时器对象的指针,该计时器对象由CreateThreadpoolTimer函数创建并返回。

当我们想向线程池注册计时器的时候,需调用SetThreadpoolTimer函数:

VOID SetThreadpoolTimer(

PTP_TIMER pTime,

PFILETIME pftDueTime,

DWORD msPeriod,

DWORD msWindowLength);

pTime标识CreateThreadpoolTimer返回的PTP_TIMER对象,pftDueTime表示第一次调用回调函数应该是什么时候,传一个负数来指定一个相对时间,但-1是一个特例,用来表示立即开始。为了指定一个绝对时间,应该传正值,这个值以100纳秒为单位,从1600年1月1日开始计算。

如果只想让定时器只触发一次,那么msPeriod参数传入0即可。msWindowsLength传入一个正数,增加随机性。

WaitForThreadpoolTimerCallbacks和CloseThreadpoolTimer分别用来等待计时器完成和释放计时器的内存。

下面是代码demo:

//定时器
TCHAR g_szCaption[100];
int g_nSecLeft = 0;
VOID CALLBACK TimeoutCallback(
PTP_CALLBACK_INSTANCE pInstance,
PVOID pvContext,
PTP_TIMER pTimer)
{
TCHAR szMsg[100];
StringCchPrintf( szMsg, _countof(szMsg), _T("You have %d seconds to respond\n"), --g_nSecLeft);
_tprintf(_T("szMsg=%s\n"), szMsg );
    }
//end

int _tmain( int argc, TCHAR* argv[] )
{
//定时器
g_nSecLeft = 10;
PTP_TIMER pTimer = CreateThreadpoolTimer(TimeoutCallback, NULL, NULL);
if (NULL == pTimer)
{
_tprintf(_T("Impossible to create the timer:%u\n"), GetLastError());
return -1;
}
ULARGE_INTEGER ulRelativeStartTime;
ulRelativeStartTime.QuadPart = (LONGLONG)-(10000000);
FILETIME ftRelativeStartTime;
ftRelativeStartTime.dwHighDateTime = ulRelativeStartTime.HighPart;
ftRelativeStartTime.dwLowDateTime = ulRelativeStartTime.LowPart;
SetThreadpoolTimer(pTimer, &ftRelativeStartTime, 1000, 0);


_tprintf(_T("You have 10 seconds to respond\n"));


while ( g_nSecLeft > 0)
{
;
}
WaitForThreadpoolTimerCallbacks(pTimer, FALSE);
CloseThreadpoolTimer(pTimer);

return 0;
}

运行结果为:


发布了65 篇原创文章 · 获赞 9 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章