《Windows编程中高精度定时的实现.pdf》由会员分享,可在线阅读,更多相关《Windows编程中高精度定时的实现.pdf(3页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、 第23卷 第4期 吉 林 工 学 院 学 报 Vol.23No.4 2002年12月 JOURNAL OF J ILIN INSTITUTE OF TECHNOLOGYDec.2002文章编号:100622939(2002)0420052203Windows编程中高精度定时的实现马丽红1,陈忠利1,覃永新2(1.鞍山科技大学 高等职业技术学院,辽宁 鞍山114002;2.中国科学院长春应用化学研究所 高分子化学与物理国家重点实验室,吉林 长春130022)摘 要:介绍了Windows编程中两种高精度时钟控制的实现方法,可达到毫秒级的时间分辨率,给出了较为完整的例子,完全能应用于实际编程中。关
2、键词:Windows编程;时间分辨率;高精度时钟中图分类号:TP301 文献标识码:A0 引 言在Windows编程中提供了多种可供选择的时间控制方法。其中一种方法是基于Windows中保留的毫秒计时器1,程序代码可以通过GetTickCount()函数读取系统时间变量的值实现对时间的控制;另一种方法是使用Windows的系统定时器,程序代码中可以使用SetTimer()函数来定义一个以毫秒计数的定时器2,应用程序就可以周期性地获得通知,并采取相应行动。以上两种技术都是应用最为普遍的方法,也是Win2dows文档推荐采用的方法。不过在某种场合,特别是在对时间精度要求较高的情况下,通过以上两种方
3、法来实现时间控制所产生的效果往往差强人意,这主要是因为受PC的内部时钟默认速率限制,以及与Windows的多任务环境保持一致所决定的。在Windows中,仍然有高精度定时的解决办法,只不过这些技术使用不多,或者有些根本未公开而已。下面介绍两种Windows下高精度时钟控制的方法。1Windows多媒体定时器的使用在Windows多媒体扩展组件中有一个高分辨率的定时器,它可以达到毫秒级的分辨率,称之为多媒体定时器3。由于每个多媒体定时器都有它自己的线程,可以不受任何挂起消息的影响就直接调用回调函数,且它不依赖于消息机制发送的WM-TIMER消息,因此多媒体定时器可以产生更为精确的结果。下面通过建
4、立一个定时器类,具体说明以上函数的用法,该定时器类可以完成与系统定时器一样的功能。#include#include class CMMTimer/定时器类/保存定时器的分辨率UINT m-wAccuracy;/保存定时器事件句柄UINT m-wTimerEventID;public:CMMTimer(UINT wAcc=1);CMMTimer();/建立指定分辨率的定时器BOOL SetTimer(UINT wAcc);/删除已建立的定时器void KillTimer(void);/建立指定时间周期间隔的定时器事件BOOL SetEvent(UINT wRes,LPTIMECALLBACK l
5、pCall,DWORD dwData);/删除已建立的定时器事件void KillEvent();CMMTimer:CMMTimer(UINT wAcc)m-wTimerEventID=0;SetTimer(wAcc);CMMTimer:CMMTimer()KillEvent();收稿日期:2002207215作者简介:马丽红(1973-),女,内蒙赤峰人,鞍山科技大学助教,主要从事计算机实时监控研究 1 1995-2004 Tsinghua Tongfang Optical Disc Co.,Ltd.All rights reserved.KillTimer();BOOL CMMTimer:
6、SetTimer(UINT wAcc)KillTimer();TIMECAPS tc;/通过timeGetDevCap函数查询系统分辨率的取值范围if(timeGetDevCaps(&tc,sizeof(TIMECAPS)=TIMERR-NOER2ROR)/确保指定的分辨率在系统取值范围内m-wAccuracy=min(max(tc.wPeriodMin,TIMER-ACCURACY),tc.wPeriodMax);timeBeginPeriod(m-wAccuracy);return TRUE;elsereturn FALSE;void CMMTimer:KillTimer(void)if(
7、m-wAccuracy)timeEndPeriod(m-wAccuracy);m-wAccuracy=0;BOOL CMMTimer:SetEvent(UINT wRes,LPTIMECALLBACK lpCall,DWORD dwData)m-wTimerEventID=timeSetEvent(wRes,/指定的时间或时间周期间隔m-wAcc,/定时器的分辨率(LPTIMECALLBACK)lpCall,/回调函数dwUserData,/传送到回调函数的数据/周期调用,若只使用一次,则用/TIME-ONESHOT TIME-PERIODIC);return(BOOL)m-wTimerEve
8、ntID;void CMMTimer:KillEvent()if(m-wTimerEventID)timeKillEvent(m-wTimerEventID);m-wTimerEventID=0;在链接时,必须加入winmm.lib库,才能编译通过。回调函数必须定义为如下的形式:voidPASCALUserProc(UINT,UINT,DWORD dwUserData,DWORD,DWORD);只须注意dwUserData参数,它作为传给回调函数的用户数据,其余参数可不予理会。2Windows内部系统时钟管理函数的使用在Windows系统驱动模块SYSTEM.DRV中存放着管理系统时钟的函数4
9、,我们可以从SYSTEM.DRV模块中取得相关的函数地址来使用。使用这些Windows内部函数,实质上是对管理系统时钟的8253计时记数芯片进行重新编程,修改其硬件中断来完成预期的任务。下面仍然通过构造一个时钟类来说明这些管理系统时钟内部函数的用法:typedef FAR PASCAL(3LPCREATESYSTEMTIMER)(WORD,FARPROC);typedef WORD FAR PASCAL(3LPKILLSYSTEMTIMER)(WORD);class CSysTimer/时钟类/保存应用程序实例句柄HINSTANCE m-hInstance;HANDLE m-hTimer;保存
10、系统时钟句柄/保存回调函数的实例地址FARPROC m-fpTimerProc;/保存CreateSystemTimer函数的地址static LPCREATESYSTEMTIMERm-fpCreateSysTimer;/保存KillSystemTimer函数的地址static LPKILLSYSTEMTIMERm-fp KillSysTimer;public:CSysTimer(HINSTANCE);CSysTimer();/建立指定时间周期间隔的定时器事件BOOL SetTimer(WORD,FARPROC);/删除已建立的定时器事件void KillTimer();LPCREATESYS
11、TEMTIMERCSysTimer:m-fpCreateSysTimer=NULL;LPKILLSYSTEMTIMER CSysTimer:m-fp Kill2SysTimer=NULL;35第4期 马丽红等:Windows编程中高精度定时的实现 1995-2004 Tsinghua Tongfang Optical Disc Co.,Ltd.All rights reserved.CSysTimer:CSysTimer(HINSTANCE hIns)m-hInstance=hIns;m-hTimer=0;m-fpTimerProc=NULL;if(!m-fpCreateSysTimer)/得
12、到SYSTEM.DRV句柄HMODULE hSystem=GetModuleHandle(“SYSTEM”);/得到SYSTEM.DRV模块中/CreateSystemTimer函数的地址(FARPROC)m-fpCreateSysTimer=GetProcAddress(hSystem,“CREATESYSTEMTIMER”);/得到SYSTEM.DRV模块中/KillSystemTimer函数的地址(FARPROC)m-fp KillSysTimer=GetProcAddress(hSystem,“KILLSYSTEMTIMER”);CSysTimer:CSysTimer()KillTim
13、er();BOOL CSysTimer:SetTimer(WORD wRes,FARPROC TimerFunc)先删除已创建的系统时钟,如有的话KillTimer();/创建回调函数TimerFunc的实例地址m-fpTimerProc=MakeProcInstance(FARPROC)TimerFunc,m-hInstance);/创建系统时钟m-hTimer=m-fpCreateSysTimer(wRes,m-fpTimerProc);void CSysTimer:KillTimer()if(m-hTimer)/删除前面由CreateSystemTimer创建/的系统时钟m-fp Kil
14、lSysTimer(m-hTimer);m-hTimer=0;if(m-fpTimerProc)释放回调函数的实例地址FreeProcInstance(m-fpTimerProc);m-fpTimerProc=NULL;3 结 语上面提到的两种高精度时钟控制的应用方法可以在对时间精度要求较高的场合下使用,而且多数情况下都可以取得令人满意的效果。其中Windows多媒体定时器在一般情况下已能够满足要求,但仍然有一定的时间延迟。Windows内部系统时钟管理函数提供的时间精度更高,不过该技术还不完善,属于未公开的技术,建议只有在不得已的情况下使用。参考文献:1Sanchez J,Canton M
15、P1Windows图形编程M.罗俊译.北京:清华大学出版社,2000.2 王华,叶爱亮,祁立学,等 1Visual C+6.0编程实例与技巧M.北京:机械工业出版社,1999.3Leinecker R C.Visual C+开发技术内幕M.北京:机械工业出版社,199914 杨亮.Windows深入剖析2内核编M.北京:清华大学出版社,19971Realization of the High2Precision Timing in Windows ProgrammingMA Li2hong1,CHEN Zhong2li1,QIN Yong2xin2(1.School of Higher Voc
16、ational Technology,Anshan University of Science and Technology,Anshan 114002,China;2.Changchun Institute of Applied Chemistry,Chinese Academy of Science,Changchun 130022,China)Abstract:Two types of high2precision time2pieces in Windows system and their application are described.The techniques are briefly discussed by giving full examples and can be applied in practical programming.Keywords:programming Windows;resolution of time;high2precision time2pieces.45吉 林 工 学 院 学 报 第23卷 1995-2004 Tsinghua Tongfang Optical Disc Co.,Ltd.All rights reserved.