C++ 延時等待(sleep/timer/wait)

原文連接:http://blog.csdn.net/tangweide/article/details/7063747linux

(—)使用_sleep()函數 

#include <iostream>   
using   namespace   std; 

_sleep(5*1000);//延時5秒 

(二)使用Delay(int   time)函數 

#include <ctime> 

void   Delay(int   time)//time*1000爲秒數 

clock_t   now   =   clock(); 

while(   clock()   -   now   <   time   ); 


Delay(5*1000);   //延時5秒 ios

 

在linux下 
#include <unistd.h> 
sleep(5)//延遲5秒 
若是你想延遲一秒之內 
那麼用 
#include <ctime> 
void   Delay(int   time)//time*1000爲秒數 

clock_t   now   =   clock(); 

while(   clock()   -   now   <   time   ); 
ide

 

VC中幾種延遲實現方案函數

方法一:VC中的WM_TIMER消息映射能進行簡單的時間控制。首先調用函數SetTimer()設置定時 間隔,如SetTimer(0,200,NULL)即爲設置200ms的時間間隔。而後在應用程序中增長定時響應函數 OnTimer(),並在該函數中添加響應的處理語句,用來完成到達定時時間的操做。這種定時方法很是 簡單,能夠實現必定的定時功能,但其定時功能如同Sleep()函數的延時功能同樣,精度很是低,最小 計時精度僅爲30ms,CPU佔用低,且定時器消息在多任務操做系統中的優先級很低,不能獲得及時響 應,每每不能知足實時控制環境下的應用。只能夠用來實現諸如位圖的動態顯示等對定時精度要求不高的狀況。如示例工程中的Timer1。 測試


方法二:VC中使用sleep()函數實現延時,它的單位是ms,如延時2秒,用sleep(2000)。精度很是 低,最小計時精度僅爲30ms,用sleep函數的不利處在於延時期間不能處理其餘的消息,若是時間太 長,就好象死機同樣,CPU佔用率很是高,只能用於要求不高的延時程序中。如示例工程中的Timer2。 spa


方法三:利用COleDateTime類和COleDateTimeSpan類結合WINDOWS的消息處理過程來實現秒級延時。如示例工程中的Timer3和Timer3_1。如下是實現2秒的延時代碼: 
   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); 
        
       //以上四行是實如今延時或定時期間能處理其餘的消息, 
       //雖然這樣能夠下降CPU的佔有率, 
       //但下降了延時或定時精度,實際應用中能夠去掉。 
       end_time = COleDateTime::GetCurrentTime()-start_time; 
   }//這樣在延時的時候咱們也可以處理其餘的消息。操作系統

    
方法四:在精度要求較高的狀況下,VC中能夠利用GetTickCount()函數,該函數的返回值是 DWORD型,表示以ms爲單位的計算機啓動後經歷的時間間隔。精度比WM_TIMER消息映射高,在較 短的定時中其計時偏差爲15ms,在較長的定時中其計時偏差較低,若是定時時間太長,就好象死機同樣,CPU佔用率很是高,只能用於要求不高的延時程序中。如示例工程中的Timer4和Timer4_1。下列代碼能夠實現50ms的精肯定時: 
    DWORD dwStart = GetTickCount(); 
    DWORD dwEnd  = dwStart; 
    do 
    { 
     dwEnd = GetTickCount()-dwStart; 
    }while(dwEnd <50); 
爲使GetTickCount()函數在延時或定時期間能處理其餘的消息,能夠把代碼改成: 
    DWORD dwStart = GetTickCount(); 
    DWORD dwEnd  = dwStart; 
    do 
    { 
       MSG  msg; 
       GetMessage(&msg,NULL,0,0); 
       TranslateMessage(&msg); 
       DispatchMessage(&msg); 
       dwEnd = GetTickCount()-dwStart; 
    }while(dwEnd <50); 
雖然這樣能夠下降CPU的佔有率,並在延時或定時期間也能處理其餘的消息,但下降了延時或定時精度。 .net


方法五:與GetTickCount()函數相似的多媒體定時器函數DWORD timeGetTime(void),該函數定時精 度爲ms級,返回從Windows啓動開始通過的毫秒數。微軟公司在其多媒體Windows中提供了精肯定時器的底 層API持,利用多媒體定時器能夠很精確地讀出系統的當前時間,而且能在很是精確的時間間隔內完成一 個事件、函數或過程的調用。不一樣之處在於調用DWORD timeGetTime(void) 函數以前必須將 Winmm.lib 和 Mmsystem.h 添加到工程中,不然在編譯時提示DWORD timeGetTime(void)函數未定義。因爲使用該 函數是經過查詢的方式進行定時控制的,因此,應該創建定時循環來進行定時事件的控制。如示例工程中的Timer5和Timer5_1。 orm


方法六:使用多媒體定時器timeSetEvent()函數,該函數定時精度爲ms級。利用該函數能夠實現週期性的函數調用。如示例工程中的Timer6和Timer6_1。函數的原型以下: 
    MMRESULT timeSetEvent( UINT uDelay, 
                UINT uResolution, 
                LPTIMECALLBACK lpTimeProc, 
                WORD dwUser, 
                UINT fuEvent ) 
  該函數設置一個定時回調事件,此事件能夠是一個一次性事件或週期性事件。事件一旦被激活,便調用指定的回調函數, 成功後返回事件的標識符代碼,不然返回NULL。函數的參數說明以下: 
    uDelay:以毫秒指定事件的週期。 
    Uresolution:以毫秒指定延時的精度,數值越小定時器事件分辨率越高。缺省值爲1ms。 
    LpTimeProc:指向一個回調函數。 
    DwUser:存放用戶提供的回調數據。 
    FuEvent:指定定時器事件類型: 
    TIME_ONESHOT:uDelay毫秒後只產生一次事件 
    TIME_PERIODIC :每隔uDelay毫秒週期性地產生事件。    
  具體應用時,能夠經過調用timeSetEvent()函數,將須要週期性執行的任務定義在LpTimeProc回調函數 中(如:定時採樣、控制等),從而完成所需處理的事件。須要注意的是,任務處理的時間不能大於週期間隔時間。另外,在定時器使用完畢後, 應及時調用timeKillEvent()將之釋放。 blog

方法七:對於精確度要求更高的定時操做,則應該使用QueryPerformanceFrequency()和 QueryPerformanceCounter()函數。這兩個函數是VC提供的僅供Windows 95及其後續版本使用的精確時間函數,並要求計算機從硬件上支持精肯定時器。如示例工程中的Timer七、Timer7_一、Timer7_二、Timer7_3。 QueryPerformanceFrequency()函數和QueryPerformanceCounter()函數的原型以下:     BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);     BOOL QueryPerformanceCounter(LARGE_INTEGER *lpCount);   數據類型ARGE_INTEGER既能夠是一個8字節長的整型數,也能夠是兩個4字節長的整型數的聯合結構, 其具體用法根據編譯器是否支持64位而定。該類型的定義以下:     typedef union _LARGE_INTEGER     {       struct       {        DWORD LowPart ;// 4字節整型數        LONG HighPart;// 4字節整型數       };       LONGLONG QuadPart ;// 8字節整型數           }LARGE_INTEGER ;   在進行定時以前,先調用QueryPerformanceFrequency()函數得到機器內部定時器的時鐘頻率, 而後在須要嚴格定時的事件發生以前和發生以後分別調用QueryPerformanceCounter()函數,利用兩次得到的計數之差及時鐘頻率,計算出事件經 歷的精確時間。下列代碼實現1ms的精肯定時:     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.001);   其定時偏差不超過1微秒,精度與CPU等機器配置有關。 下面的程序用來測試函數Sleep(100)的精確持續時間:     LARGE_INTEGER litmp;     LONGLONG QPart1,QPart2;     double dfMinus, dfFreq, dfTim;     QueryPerformanceFrequency(&litmp);     dfFreq = (double)litmp.QuadPart;// 得到計數器的時鐘頻率     QueryPerformanceCounter(&litmp);     QPart1 = litmp.QuadPart;// 得到初始值     Sleep(100);     QueryPerformanceCounter(&litmp);     QPart2 = litmp.QuadPart;//得到停止值     dfMinus = (double)(QPart2-QPart1);     dfTim = dfMinus / dfFreq;// 得到對應的時間值,單位爲秒     因爲Sleep()函數自身的偏差,上述程序每次執行的結果都會有微小偏差。下列代碼實現1微秒的精肯定時:     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); 其定時偏差通常不超過0.5微秒,精度與CPU等機器配置有關。

相關文章
相關標籤/搜索