天天看點

關于VC中的時間函數讨論

關于在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