《vc++七种延时方式》由会员分享,可在线阅读,更多相关《vc++七种延时方式(4页珍藏版)》请在金锄头文库上搜索。
1、VC+七种延时方式 方式一:VC 中的 WM_TIMER 消息映射能进行简单的时间控制。首先调用函数 SetTimer() 设置定时间隔,如 SetTimer(0,200,NULL)即为设置 200ms 的时间间隔。然后在应用程序中 增加定时响应函数 OnTimer(),并在该函数中添加响应的处理语句,用来完成到达定时时 间的操作。这种定时方法非常简单,可以实现一定的定时功能,但其定时功能如同 Sleep() 函数的延时功能一样,精度非常低,最小计时精度仅为,精度非常低,最小计时精度仅为 30ms,CPU 占用低,且定时器消 息在多任务操作系统中的优先级很低,不能得到及时响应,往往不能满足实时
2、控制环境下 的应用。只可以用来实现诸如位图的动态显示等对定时精度要求不高的情况。如示例工程 中的 Timer1。 方式二:VC 中使用 sleep()函数实现延时,它的单位是 ms,如延时 2 秒,用 sleep(2000)。 精度非常低精度非常低,最小计时精度仅为 30ms,用 sleep 函数的不利处在于延时期间不能处理其他 的消息,如果时间太长,就好象死机一样,CPU 占用率非常高占用率非常高,只能用于要求不高的延时 程序中。如示例工程中的 Timer2。 方式三:利用 COleDateTime 类和 COleDateTimeSpan 类结合 WINDOWS 的消息处理过程 来实现秒级延
3、时。如示例工程中的 Timer3 和 Timer3_1。以下是实现 2 秒的延时代码: COleDateTimestart_time=COleDateTime:GetCurrentTime(); COleDateTimeSpanend_time=COleDateTime:GetCurrentTime()-start_time; while(end_time.GetTotalSeconds() 方式四:在精度要求较高的情况下,VC 中可以利用 GetTickCount()函数,该函数的返回值 是 DWORD 型,表示以 ms 为单位的计算机启动后经历的时间间隔。精度比 WM_TIMER 消息映射
4、高,在较短的定时中其计时误差为计时误差为 15ms,在较长的定时中其计时误差较低,如果 定时时间太长,就好象死机一样,CPU 占用率非常高,只能用于要求不高的延时程序中。 如示例工程中的 Timer4 和 Timer4_1。下列代码可以实现 50ms 的精确定时: DWORDdwStart=GetTickCount(); DWORDdwEnd=dwStart; do dwEnd=GetTickCount()-dwStart; while(dwEnd) 为使 GetTickCount()函数在延时或定时期间能处理其他的消息,可以把代码改为:DWORDdwStart=GetTickCount();
5、 DWORDdwEnd=dwStart; do MSGmsg; GetMessage( TranslateMessage( DispatchMessage( dwEnd=GetTickCount()-dwStart; while(dwEnd) 虽然这样可以降低 CPU 的占有率,并在延时或定时期间也能处理其他的消息,但降低了延 时或定时精度。 方式五:与 GetTickCount()函数类似的多媒体定时器函数 DWORDtimeGetTime(void),该函 数定时精度为 ms 级,返回从 Windows 启动开始经过的毫秒数。微软公司在其多媒体 Windows 中提供了精确定时器的底层 A
6、PI 持,利用多媒体定时器可以很精确地读出系统的 当前时间,并且能在非常精确的时间间隔内完成一个事件、函数或过程的调用。不同之处 在于调用 DWORDtimeGetTime(void)函数之前必须将 Winmm.lib 和 Mmsystem.h 添加到工 程中,否则在编译时提示 DWORDtimeGetTime(void)函数未定义。由于使用该函数是通过 查询的方式进行定时控制的,所以,应该建立定时循环来进行定时事件的控制。如示例工 程中的 Timer5 和 Timer5_1。 方式六:使用多媒体定时器 timeSetEvent()函数,该函数定时精度为该函数定时精度为 ms 级级。利用该函数
7、可 以实现周期性的函数调用。如示例工程中的 Timer6 和 Timer6_1。函数的原型如下:MMRESULTtimeSetEvent(UINTuDelay, UINTuResolution, PTIMECALLBACKlpTimeProc, WORDdwUser, UINTfuEvent) 该函数设置一个定时回调事件,此事件可以是一个一次性事件或周期性事件。事件一旦被 激活,便调用指定的回调函数,成功后返回事件的标识符代码,否则返回 NULL。函数的 参数说明如下: uDelay:以毫秒指定事件的周期。 Uresolution:以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为
8、1ms。 LpTimeProc:指向一个回调函数。 DwUser:存放用户提供的回调数据。 FuEvent:指定定时器事件类型: TIME_ONESHOT:uDelay 毫秒后只产生一次事件 TIME_PERIODIC:每隔 uDelay 毫秒周期性地产生事件。 具体应用时,可以通过调用 timeSetEvent()函数,将需要周期性执行的任务定义在 LpTimeProc 回调函数中(如:定时采样、控制等),从而完成所需处理的事件。需要注意的 是,任务处理的时间不能大于周期间隔时间。另外,在定时器使用完毕后,应及时调用 timeKillEvent()将之释放。 方式七:对于精确度要求更高的定时
9、操作,则应该使用 QueryPerformanceFrequency()和 QueryPerformanceCounter()函数。这两个函数是 VC 提供的仅供 Windows95 及其后续版本 使用的精确时间函数,并要求计算机从硬件上支持精确定时器。如示例工程中的 Timer7、Timer7_1、Timer7_2、Timer7_3。 QueryPerformanceFrequency()函数和 QueryPerformanceCounter()函数的原型如下: BOOLQueryPerformanceFrequency(LARGE_INTEGERlpFrequency); BOOLQuer
10、yPerformanceCounter(LARGE_INTEGERlpCount); 数据类型 ARGE_INTEGER 既可以是一个 8 字节长的整型数,也可以是两个 4 字节长的整 型数的联合结构,其具体用法根据编译器是否支持 64 位而定。该类型的定义如下: typedefunion_LARGE_INTEGER struct DWORDLowPart; /4 字节整型数 LONGHighPart; /4 字节整型数 ; LONGLONGQuadPart; /8 字节整型数 LARGE_INTEGER; 在进行定时之前,先调用 QueryPerformanceFrequency()函数获得
11、机器内部定时器的时钟频 率,然后在需要严格定时的事件发生之前和发生之后分别调用 QueryPerformanceCounter() 函数,利用两次获得的计数之差及时钟频率,计算出事件经历的精确时间。 下列代码实现 1ms 的精确定时: LARGE_INTEGERlitmp; LONGLONGQPart1,QPart2; doubledfMinus,dfFreq,dfTim; QueryPerformanceFrequency( dfFreq=(double)litmp.QuadPart; /获得计数器的时钟频率 QueryPerformanceCounter( QPart1=litmp.Qua
12、dPart; /获得初始值 do QueryPerformanceCounter( QPart2=litmp.QuadPart; /获得中止值 dfMinus=(double)(QPart2-QPart1); dfTim=dfMinus/dfFreq; /获得对应的时间值,单位为秒 while(dfTim) 其定时误差不超过 1 微秒,精度与 CPU 等机器配置有关。 下面的程序用来测试函数 Sleep(100)的精确持续时间: LARGE_INTEGERlitmp; LONGLONGQPart1,QPart2; doubledfMinus,dfFreq,dfTim; QueryPerform
13、anceFrequency( dfFreq=(double)litmp.QuadPart; /获得计数器的时钟频率 QueryPerformanceCounter( QPart1=litmp.QuadPart; /获得初始值 Sleep(100); QueryPerformanceCounter( QPart2=litmp.QuadPart; /获得中止值 dfMinus=(double)(QPart2-QPart1); dfTim=dfMinus/dfFreq; /获得对应的时间值,单位为秒 由于 Sleep()函数自身的误差,上述程序每次执行的结果都会有微小误差。 下列代码实现 1 微秒的
14、精确定时: LARGE_INTEGERlitmp; LONGLONGQPart1,QPart2; doubledfMinus,dfFreq,dfTim; QueryPerformanceFrequency( dfFreq=(double)litmp.QuadPart; /获得计数器的时钟频率 QueryPerformanceCounter( QPart1=litmp.QuadPart; /获得初始值 do QueryPerformanceCounter( QPart2=litmp.QuadPart; /获得中止值 dfMinus=(double)(QPart2-QPart1); dfTim=dfMinus/dfFreq; /获得对应的时间值,单位为秒 while(dfTim)其定时误差一般不超过 0.5 微秒微秒,精度与 CPU 等机器配置有关。* 百度空间文字排版的功能真差劲。 。 。