關于在VC中時間函數的事業問題在論壇有不少的文章讨論,下面結合讨論結果和相關的知識做個總結。
先從一個如何在程式中延時的問題談起,延時的方法有
方法一:
使用sleep函數,它的最小機關是1ms,如延時2秒,用sleep(2000)。
方法二:
使用sleep函數的不利處在于期間不能處理其他的消息,如果時間太長,就好象當機一樣,是以我們利用
COleDateTime類和COleDateTimeSpan類結合WINDOWS的消息處理過程來實作延時:
COleDateTime start_time = COleDateTime::GetCurrentTime();
COleDateTimeSpan end_time = COleDateTime::GetCurrentTime()-start_time;
While(end_time.GetTotalSeconds() <= 2) //實作延時2秒
{
MSG? msg;
GetMessage(&msg,NULL,0,0);
TranslateMessage(&msg);
DispatchMessage(&msg);
End_time = ColeDateTime::GetCurrentTime-start_time;
}//這樣在延時的時候我們也能夠處理其他的消息。
方法三:
可以采用GetTickCount()函數,該函數的傳回值是DWORD型,表示以毫秒為機關的計算機啟動後經曆的時間間隔。
DWORD dwStart = GetTickCount();
DWORD dwEnd = dwStart;
do
{
MSG? msg;?
GetMessage(&msg,NULL,0,0);?
TranslateMessage(&msg);
DispatchMessage(&msg);
dwEnd = GetTickCount();?
} while((dwEnd - dwStart)? <=? 2000);
上面的方法在延時的精确度上,很多時候不能滿足我們的要求,下面是一種更精确的微秒級延時:
LARGE_INTEGER litmp ;
LONGLONG QPart1,QPart2 ;
double d=0;
QueryPerformanceCounter(&litmp) ;
// 獲得初始值
QPart1 = litmp.QuadPart ;
while (d<40)//你想要的時間
{
QueryPerformanceCounter(&litmp) ;
QPart2 = litmp.QuadPart ;
d=(double)(QPart2 - QPart1);
}
再看看僅供WIN9X使用的高精度定時器:QueryPerformanceFrequency()和QueryPerformanceCounter(),要求計算機從硬體上支援高精度定時器。函數的原形是:
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
BOOL QueryPerformanceCounter (LARGE_INTEGER *lpCount);
資料類型LARGEINTEGER既可以是一個作為8位元組長的整數,也可以是作為兩個4位元組長的整數的聯合結構,其具體用法根據編譯器是否支援64位而定。該類型的定義如下:
typeef union _ LARGE_INTEGER
{
struct
{
DWORD LowPart;
LONG? HighPart;
};
LONGLONG QuadPart;
} LARGE_INTEGER;
在定時前應該先調用QueryPerformanceFrequency()函數獲得機器内部計時器的時鐘頻率。接着在需要嚴格計時的事件發生前和發生之後分别調用QueryPerformanceCounter(),利用兩次獲得的計數之差和時鐘頻率,就可以計算出事件經曆的精确時間。測試函數SLEEP(100)的精确持續時間方法:
LARGE_INTEGER litmp;
LONGLONG qt1,qt2;
double dft,dff,dfm;
QueryPerformanceFrequency(&litmp);//獲得時鐘頻率
dff=(double)litmp.QuadPart;
QueryPerformanceCounter(&litmp);//獲得初始值
qt1=litmp.QuadPart;Sleep(100);
QueryPerformanceCounter(&litmp);//獲得終止值
qt2=litmp.QuadPart;
dfm=(double)(qt2-qt1);
dft=dfm/dff;//獲得對應的時間值
需要注意的是DFT計算的結果機關是秒。
參考連接配接:
http://dev.csdn.net/develop/article/31/31188.shtm
http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=195559