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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章