微軟公司在其多媒體Windows中提供了精確定時器的底層API支持。利用多媒體定時器可以很精確地讀出系統的當前時間,並且能在非常精確的時間間隔內完成一個事件、函數或過程的調用。利用多媒體定時器的基本功能,可以通過兩種方法實現精確定時。1)使用timeGetTime()函數,該函數定時精度為ms級,返回從Windows啟動開始所經過的時間。由於使用該函數是通過查詢的方式進行定時控制的,所以,應該建立定時循環來進行定時事件的控制。2)使用timeSetEvent()函數,該函數原型如下:
MMRESULT timeSetEvent(UINT uDelay,UINT uResolution,LPTIMECALLBACK lpTimeProc,DWORD dwUser,INT fuEvent);
該函數的參數說明如下:參數uDelay表示延遲時間;參數uResolution表示時間精度,在Windows中缺省值為 1ms;lpTimeProc表示回調函數,為用戶自定義函數,定時調用;參數dwUser表示用戶提供的回調數據;參數fuEvent為定時器的事件類型,TIME_ONESHOT表示執行一次;TIME_PERIODIC:周期性執行。具體應用時,可以通過調用timeSetEvent()函數,將需要周期性執行的任務定義在lpTimeProc回調函數中(如:定時采樣、控制等),從而完成所需處理的事件。需要注意的是:任務處理的時間不能大於周期間隔時間。另外,在定時器使用完畢后,應及時調用 timeKillEvent()將之釋放。
應用:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#pragma comment(lib,"Winmm.lib")
void PASCAL OneMilliSecondProc(UINT wTimerID, UINT msg,DWORD dwUser,DWORD dwl,DWORD dw2)
{
printf("%s\n", (char*)dwUser);
}
void main()
{
UINT TimerID; //定義定時器句柄
char buf[]="sdffadfa";
if((TimerID = timeSetEvent(20, 1,(LPTIMECALLBACK)OneMilliSecondProc,buf,TIME_PERIODIC)) == 0)//周期調用定時處理函數
{
printf("error!\n");
}
else
{
printf("ok!\n");
}
while (1)
{
printf("hello!\n");
Sleep(1000);
timeKillEvent(TimerID);
}
}
//當不得已創建了很多定時器對象時,可以考慮使用CreateTimerQueueTimer替換。