Windows定時精度比較
方式一:VC中的WM_TIMER消息映射能進行簡單的時間控制。首先調用函數SetTimer()設置定時間隔,如SetTimer(0,200,NULL)即爲設置200ms的時間間隔。然後在應用程序中增加定時響應函數 OnTimer(),並在該函數中添加響應的處理語句,用來完成到達定時時間的操作。這種定時方法非常簡單,可以實現一定的定時功能,但其定時功能如同Sleep()函數的延時功能一樣,精度非常低,最小計時精度僅爲30ms,CPU佔用低,且定時器消息在多任務操作系統中的優先級很低,不能得到及時響應,往往不能滿足實時控制。
方式二:VC中使用sleep()函數實現延時,它的單位是ms,如延時2秒,用sleep(2000)。精度非常 低;如下例測試Sleep函數的定時精度。
#include "stdio.h"
#include "windows.h"
int main()
{
LARGE_INTEGER litmp;
LONGLONGQPart1,QPart2;
double dfMinus, dfFreq, dfTim;
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;QueryPerformanceCounter(&litmp);
QPart1 =litmp.QuadPart;
Sleep(2000);
QueryPerformanceCounter(&litmp);
QPart2 =litmp.QuadPart;
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus /dfFreq;
printf("%lf\n",dfTim);
System("pause");
}
輸出結果:
誤差爲711us,無法達到實時性的要求。
方式三:在精度要求較高的情況下,VC中可以利用GetTickCount()函數,該函數的返回值是DWORD型,表示以ms爲單位的計算機啓動後經歷的時間間隔。精度比WM_TIMER消息映射高。
如下例實現30ms的精確定時。
DWORD dwStart = GetTickCount();
DWORD dwEnd = dwStart;
do
{
dwEnd = GetTickCount()-dwStart;
}while(dwEnd <30);
方式四:對於精確度要求更高的定時操作,則應該使用QueryPerformanceFrequency()和 QueryPerformanceCounter()函數。
QueryPerformanceFrequency()函數和QueryPerformanceCounter()函數的原型如下:
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpCount);
數據類型ARGE_INTEGER既可以是一個8字節長的整型數,也可以是兩個4字節長的整型數的聯合結構。
typedef union _LARGE_INTEGER
{
struct
{
DWORD LowPart ;// 4字節整型數
LONG HighPart;// 4字節整型數
};
LONGLONG QuadPart ;// 8字節整型數
}LARGE_INTEGER ;
如下實現精度爲1um的定時。
LARGE_INTEGER litmp;
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfTim;
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;// 獲得計數器的時鐘頻率
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;// 獲得初始值
do
{
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;//獲得中止值
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfFreq;// 獲得對應的時間值,單位爲秒
}while(dfTim<0.000001);