定时函数的应用综述

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

定时函数的应用综述当我们在衡量一个函数的运行时间,或者是判断一个算法的时间效率,或者在程序中我们需要一个定时器来定时执行一个特定的操作,如闹铃、时钟、多媒体、游戏动画等,都要用到时间函数。编译器和时间函数为我们提供了很多时间函数,而这些函数的精度和用法也是各不相同的。下面我们就对几种常见的定时函数进行比较、详述:1、Sleep函数用法精度原理及说明备注VOIDSleep(DWORDdwMilliseconds//休眠的毫秒数);其精度很低,系统越忙,精度越低,其精度取决于当前线程及其他线程的优先级以及线程数量等因素Sleep函数是使调用Sleep函数的线程休眠,线程主动放弃时间片。当经过指定的时间间隔后,再启动线程,继续执行代码。Sleep函数并不能起到定时的作用,主要作用是延时。在一些多线程中可能会看到Sleep(0);其主要目的是让出时间片。Sleep(1000);//休眠一秒钟当你要创建一个窗口是使用这个函数必须要小心。因为当一个进程创建一个窗口时,它必须处理消息,而消息广播被发送到系统所有的窗口中,这时你如果在一个线程中使用了Sleep函数来无限延迟,可能会导致系统死锁。所以在此时你可以应用函数MsgWaitForMultipleObjects或MsgWaitForMultipleObjectsEx来代替Sleep(MSDN)2、MFC中的timer事件用法精度原理及说明备注先使用SetTimer()来定时再在程序中增加定时响应函数OnTimer()并在此函数中增加相应的处理语句完成时间到时的操作精度在毫秒级别,一般其响应时间为55ms,且系统越忙精度越差。原理与Sleep一样,不同的是timer是一个定时器,可以指定回调函数,默认为OnTimer().常用于做电子时钟或者在游戏动画中使用它。3、C中的Time应用用法精度原理及说明备注time_tt;time(&t);Time函数是获取当前时间秒级别用于获取当前时间比如我们做一个电子时钟,就可以用它来获取系统当前时间4、COM中的COledateTime,COleDateTimeSpan类的使用用法精度原理及说明备注COleDateTimestart_time=COleDateTime::GetCurrentTime();COleDateTimeSpanend_time=COleDateTime::GetCurrentTime()-start_time;While(end_time.GetTotalSeconds()2){//处理延时或定时期间能处理其他的消息DoSomething()end_time=COleDateTime::GetCurrentTime-start_time;}秒级别以上代表延时2秒,而这两秒内我们可以循环调用DoSomething(),从而实现在延时的时候我们也能够处理其他的函数,或者消息。COleDateTime,COleDateTimeSpan是MFC中CTime,CTimeSpan在COM中的应用,所以,上面的方法对于CTime,CTimeSpa同样有效。5、C语言中的时钟周期clock的使用用法精度原理及说明备注clock_tstart=clock();Sleep(100);clock_tend=clock();doubled=(double)(start-end)/CLOCKS_PER_SEC;ms级别,对于短时间内的定时或者延时可以达到ms级别,对于时间比较长的定时或者延迟精度还是不够。原理:clock()是获取计算机启动后的时间间隔。在windows下CLOCKS_PER_SEC为1000。6、Windows下的GetTickCount的使用用法精度原理及说明备注DWORDstart=GetTickCount();Sleep(100);DWORDend=GetTickCount();其时间精度要比clock高,WindowsNT3.5以后10ms.WindowsNT3.116ms.Windows95andlater55msGetTickCount()是获取系统启动后的时间间隔。通过进入函数开始定时,到退出函数结束定时,从而可以判断出函数的执行时间,这种时间也并非是函数或者算法的真实执行时间,因为在函数和算法线程不可能一直占用CPU,对于所有判断执行时间的函数都是一样,不过基本上已经很准确,可以通过查询进行定时。GetTickCount()和Clock()函数是向主板BIOS要realtimeclock时间,会有中断产生,以及延迟问题。常用于多媒体7、Windows下的timeGetTime使用用法精度原理及说明备注timeBeginPeriod(1);DWORDstart=timeGetTime();Sleep(100);DWORDend=timeGetTime();timeEndPeriod(1);毫秒与GetTickCount()相当。但是和GetTickCount相比,timeGetTime可以通过timeBeginPeriod,timeEndPeriod设置定时器的最小解析精度timeGetTime也时常用于多媒体定时器中,可以通过查询进行定时。通过查询进行定时,本身也会影响定时器的定时精度。timeBeginPeriod,timeEndPeriod必须成对出现。需要包含Mmsystem.h,Windows.h,加入静态库Winmm.libWindowsCE下需要包含需要包含Mmsystem.h,Windows.h,加入静态库mmtimer.lib8、Windows下的TimeSetEvent函数的使用用法精度原理及说明备注需要调用:timeGetDevCaps()timeBeginPeriod()然后调用TimeSetEvent()最后调用:timeKillEvent()定义一个回调函数:staticVOIDCALLBACKStopwatchTimer(UINTuTimerID,UINTuMsg,DWORD_PTRdwUser,DWORD_PTRdw1,DWORD_PTRdw2)毫秒Timer是一个定时器,而以上我们提到几种时间函数或者类型,实现定时功能只能通过轮训来实现,也就是必须另外创建一个线程单独处理,这样会影响定时精度,好在windows提供了内置的定时器timeSetEvent。具体应用时,可以通过调用timeSetEvent()函数,将需要周期性执行的任务定义在lpFunction回调函数中(如:定时采样、控制等),从而完成所需处理的事件。需要注意的是:任务处理的时间不能大于周期间隔时间。另外,在定时器使用完毕后,应及时调用timeKillEvent()将之释放。原理:可以理解为代回调函数的timeGetTimetimeBeginPeriod,timeEndPeriod置定时器的最小解析精度必须成对出现。需要包含Mmsystem.h,Windows.h,加入静态库Winmm.libWindowsCE下需要包含需要包含Mmsystem.h,Windows.h,加入静态库mmtimer.lib9、高精度时控函数QueryPerformanceFrequency,QueryPerformanceCounter使用用法精度原理及说明备注LARGE_INTEGERm_nFreq;LARGE_INTEGERm_nBeginTime;LARGE_INTEGERnEndTime;QueryPerformanceFrequency(&m_nFreq);//获取时钟周期QueryPerformanceCounter(&m_nBeginTime);//获取时钟计数Sleep(100);QueryPerformanceCounter(&nEndTime);cout(nEndTime.QuadPart-m_nBeginTime.QuadPart)*1000/m_nFreq.QuadPartendl;计算机获取硬件支持,精度较高,可以用来判断其他时间函数的精度范围:CPU上也有一个计数器,以机器的clock为单位,可以通过rdtsc读取,而不用中断,因此其精度与系统时间相当。小结:以上提到的9种时间函数,由于他们的用处不同,其精度也有很大的差异,用户可以根据不同的需求选择合适的时间函数。本文原始资料来源于网络,经个人加工形成,有些函数由于没有经过自己的测试,资料不一定准确,在选择了具体的函数之后,使用时尚须查阅该函数具体的资料。我在程序中使用过的函数举例:1:Sleep(1000)//延时1s,多用于多线程程序中,如果在单个线程的程序中使用,有类似死机现象。2、Timer事件:该函数使用比较简单,但由于其精度与系统繁忙程度有关,在不需精确定时的场合应用非常好用,但如果需要精确定时,建议不要使用;(1)定时setTimer(1,1000,NULL)//为定时器一设置一个1秒的周期(2)在应用程序中添加OnTime(){CDC*pDC;pDC-TextOut(100,100,“Thisisatest!”);}//消息响应函数,在该函数中处理你想有响应的事件。3、TimeSetEvent()函数//加入静态链接库Winmm.lib(Windowsxp),mmTimer.lib(WindowsCE)#includeMmsystem.h//已经包含了的头文件#includeWindows.h#defineONE_MILLI_SECOND100//定义1ms和2s时钟间隔,以ms为单位;#defineTWO_SECOND2000#defineTIMER_ACCURACY1//定义时钟分辨率,以ms为单位UINTwTimerRes_1ms,wTimerRes_2s;//定义时间间隔UINTwAccuracy;//定义分辨率UINTTimerID_1ms,TimerID_2s;//定义定时器句柄staticVOIDCALLBACKOneMilliSecondProc(UINTuTimerID,UINTuMsg,DWORD_PTRdwUser,DWORD_PTRdw1,DWORD_PTRdw2){//定义计数器staticintms=0;CDAQView*app=(CDAQView*)dwUser;//取得系统时间,以ms为单位DWORDosBinaryTime=GetTickCount();//输出计数器值和当前系统时间app-Timer();}CDAQView::CDAQView(){//TODO:addconstructioncodehere//给时间间隔变量赋值wTimerRes_1ms=ONE_MILLI_SECOND;wTimerRes_2s=TWO_SECOND;TIMECAPStc;//利用函数timeGetDevCaps取出系统分辨率的取值范围,如果无错则继续;if(timeGetDevCaps(&tc,sizeof(TIMECAPS))==TIMERR_NOERROR){wAccuracy=min(max(tc.wPeriodMin,//分辨率的值不能超出系统的取值范围TIMER_ACCURACY),tc.wPeriodMax);//调用timeBeginPeriod函数设置定时器的分辨率timeBeginPeriod(wAccuracy);}CDAQView::~CDAQView(){timeKillEvent(TimerID_1ms);//删除两个定时器//删除设置的分辨率timeEndPeriod(wAccuracy);}voidCDAQView::StartOneMilliSecondTimer(){if((TimerID_1ms=timeSetEvent(wTimerRes_1ms,wAccuracy,(LPTIMECALLBACK)OneMilliSecondProc,//回调函数;(DWORD)this,//用户传送到回调函数的数据;TIME_PERIODIC)==10))//周期

1 / 6
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功