VC中提供了很多关于时间操作的函数,利用它们控制程序能够精确地完成定时和计时操作。本文详细介绍了
图一 图像描述
方式一:VC中的WM_TIMER消息映射能进行简单的时间控制。首先调用函数SetTimer()设置定时
方式二:VC中使用sleep()函数实现延时,它的单位是ms,如延时2秒,用sleep(2000)。精度非常
方式三:利用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 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的占有率,并在延时或定时期间也能处理其他的消息,但降低了延时或定时精度。
MMRESULT timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, WORD dwUser, UINT fuEvent )该函数设置一个定时回调事件,此事件可以是一个一次性事件或周期性事件。事件一旦被激活,便调用指定的回调函数,
uDelay:以毫秒指定事件的周期。 Uresolution:以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为1ms。 LpTimeProc:指向一个回调函数。 DwUser:存放用户提供的回调数据。 FuEvent:指定定时器事件类型: TIME_ONESHOT:uDelay毫秒后只产生一次事件 TIME_PERIODIC :每隔uDelay毫秒周期性地产生事件。具体应用时,可以通过调用timeSetEvent()函数,将需要周期性执行的任务定义在LpTimeProc回调函数
BOOL QueryPerformanceFrequenc数据类型ARGE_INTEGER既可以是一个8字节长的整型数,也可以是两个4字节长的整型数的联合结构,y(LARGE_INTEGER *lpFrequency); BOOL QueryPerformanceCounter(LARGE_INTEGER *lpCount);
typedef union _LARGE_INTEGER { struct { DWORD LowPart ;// 4字节整型数 LONG HighPart;// 4字节整型数 }; LONGLONG QuadPart ;// 8字节整型数 }LARGE_INTEGER ;在进行定时之前,先调用QueryPerformanceFrequenc
LARGE_INTEGER litmp; LONGLONG QPart1,QPart2; double dfMinus, dfFreq, dfTim; QueryPerformanceFrequenc其定时误差不超过1微秒,精度与CPU等机器配置有关。 下面的程序用来测试函数Sleep(100)的精确持续时间:y(&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);
LARGE_INTEGER litmp; LONGLONG QPart1,QPart2; double dfMinus, dfFreq, dfTim; QueryPerformanceFrequenc由于Sleep()函数自身的误差,上述程序每次执行的结果都会有微小误差。下列代码实现1微秒的精确定时:y(&litmp); dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率 QueryPerformanceCounter(&litmp); QPart1 = litmp.QuadPart;// 获得初始值 Sleep(100); QueryPerformanceCounter(&litmp); QPart2 = litmp.QuadPart;//获得中止值 dfMinus = (double)(QPart2-QPart1); dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒
LARGE_INTEGER litmp; LONGLONG QPart1,QPart2; double dfMinus, dfFreq, dfTim; QueryPerformanceFrequenc其定时误差一般不超过0.5微秒,精度与CPU等机器配置有关。y(&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);
原文地址:http://blog.csdn.net/wangwb0820/article/details/45244655