VC中提供了很多关于时间操作的函数,编写程序时我们可以跟据定时的不同精度要求选择不同的时间函数来完成定时和计时操作。

方式一:VC中的WM_TIMER消息映射能进行简单的时间控制。首先调用函数SetTimer()设置定时 间隔,如SetTimer(0,200,NULL)即为设置200ms的时间间隔。然后在应用程序中增加定时响应函数 OnTimer(),并在该函数中添加响应的处理语句,用来完成到达定时时间的操作。这种定时方法非常简单,可以实现一定的定时功能,但其定时功能如同Sleep()函数的延时功能一样,精度非常低,最小计时精度仅为18ms。CPU占用低,且定时器消息在多任务操作系统中的优先级很低,不能得到及时响 应,往往不能满足实时控制环境下的应用。只可以用来实现诸如位图的动态显示等对定时精度要求不高的情况。

方式二:VC中使用sleep()函数实现延时,它的单位是ms,如延时2秒,用sleep(2000)。精度非常 低,最小计时精度仅为30ms,用sleep函数的不利处在于延时期间不能处理其他的消息,如果时间太 长,就好象死机一样,CPU占用率非常高,只能用于要求不高的延时程序中。

方式三:利用COleDateTime类和COleDateTimeSpan类结合WINDOWS的消息处理过程来实现秒级延时。以下是实现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占用率非常高,只能用于要求不高的延时程序中。下列代码可以实现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的占有率,并在延时或定时期间也能处理其他的消息,但降低了延时或定时精度。

方式五:与GetTickCount()函数类似的多媒体定时器函数DWORD timeGetTime(void),该函数定时精 度为ms级,返回从Windows启动开始经过的毫秒数。微软公司在其多媒体Windows中提供了精确定时器的底 层API持,利用多媒体定时器可以很精确地读出系统的当前时间,并且能在非常精确的时间间隔内完成一 个事件、函数或过程的调用。不同之处在于调用DWORD timeGetTime(void) 函数之前必须将 Winmm.lib 和 Mmsystem.h 添加到工程中,否则在编译时提示DWORD timeGetTime(void)函数未定义。由于使用该 函数是通过查询的方式进行定时控制的,所以,应该建立定时循环来进行定时事件的控制。

方式六:使用多媒体定时器timeSetEvent()函数,该函数定时精度为ms级。利用该函数可以实现周期性的函数调用。函数的原型如下:
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()将之释放。

方式七:对于精确度要求更高的定时操作,则应该使用QueryPerformanceFrequency()和 QueryPerformanceCounter()函数。这两个函数是VC提供的仅供Windows 95及其后续版本使用的精确时间函数,并要求计算机从硬件上支持精确定时器。

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);

另外值得一提的是,由于机器自身的差别和机器运行负荷的不同,要实现非常精确定时实际上是很难做到的,以上定时精度都是理论上能够达到的,实际运行中要降低很多。第七种方式中做实验精度基本能准确到0.1毫秒以内,这对于一般的程序来说已经足够了

windows下延时函数相关推荐

  1. windows 下实现函数打桩:拦截API方式

    windows 下实现函数打桩:拦截API方式 近期由于工作须要,開始研究函数打桩的方法. 由于不想对project做过多的改动,于是放弃了使用Google gmock的想法. 可是也足足困扰另外我一 ...

  2. Windows下的函数

    在进行Windows应用程序设计中,程序员除了需要知道有关一个函数的常用信息(例如函数的名字,近函数或远函数,返回类型以及应如何调用)之外,同时还要知道更多的内容:一个回调函数.引出函数或是一个引入函 ...

  3. linux下延时函数qt,Qt延时函数

    QT 延时函数包含在一个叫做QThread.h的类中(大小写自己改改) 在使用的时候 注意包含该文件#include 成员函数文档 QThread::QThread () 构造一个新的线程.这个线程将 ...

  4. Windows下system()函数详解

    Start~~ 在C++/C的Windows环境中,对于控制台窗口的处理,有一个函数必须知道: system(" "); 是的,没错.它可以调动Cmd控制台中的命令,来方便程序员的 ...

  5. windows下system函数的使用

    system函数 是可以调用一些DOS命令,比如 system("cls");//清屏,等于在DOS上使用cls命令 写可执行文件路径,可以运行它···· 下面列出常用的DOS命令 ...

  6. windows下创建目录函数_mkdir

    创建目录函数_mkdir(path),返回0表示成功,-1失败 只能创建一级目录,即path倒数第二级必须是已经存在,否则创建不成功. 如果需要创建多级目录,如下: char szPath[256] ...

  7. windows下socket函数一直返回-1的问题

    今天遇到了一个SOCKET初始化的问题,运行平台在linux中,在windows中调试,就出现了socket一直返回-1的错误.解决办法是增加了两段代码,在windows中要使用socket,需要先注 ...

  8. linux下mkdir头文件_Linux中mkdir函数与Windows中_mkdir函数的区别

    下面先来给大家介绍windows下_mkdir函数 #include int _mkdir( const char *dirname ); 参数: dirname是目录的路径名指针 返回值: 如果新目 ...

  9. Windows下断言的类型及实现

    一.内容综述 本文主要介绍Windows下断言assert的实现,并总结断言的不同应用准则.最后给出一个windows自定义断言的方法. 本文行文参考<Debugging Windows Pro ...

最新文章

  1. 使用此代码可以解决python包导入路径问题?
  2. 万物共享的物联网架构
  3. Flutter入门进阶之旅(九)StatelessWidget StatefullWidget
  4. ONVIF网络摄像头(IPC)客户端开发—RTSP RTCP RTP加载H264视频流
  5. nodejs模块导入导出
  6. 面向对象第一单元总结
  7. 5.Springcloud的Ribbon组件的集成及实现轮询负载均衡方式
  8. Zcash已发布ZIP 313提案
  9. map 和 hash_map 的使用方法
  10. 多线程与多进程之间比较
  11. solidworks电气元件3d库_送软件 | 零基础也可以学的EPLAN电气设计实战教程
  12. ubuntu处理openproj不能使用问题
  13. TurboMail邮件系统配置之预防邮件炸弹
  14. 物联网PaaS平台大盘点
  15. 请用android手机自带浏览器,还在用手机自带浏览器吗?推荐两款无广告、功能齐全的浏览器...
  16. 燕东微通过注册:预计年营收超20亿 亦庄国投与京东方是股东
  17. 大数据应用型产品设计方法及行业案例介绍(附110页PPT)
  18. 【模拟电路】431基准电压源
  19. 资金指数(ZJZS)指标
  20. 六度分离 (folyd算法)

热门文章

  1. ios 字体 机打动效_24种打动朋友的方法
  2. k8s(kubernetes)部署nacos(3各节点....N各节点均可以)集群
  3. Nokia计划在2009年推出多款OLED屏幕手机
  4. 小常识:手机被偷后如何让小偷不能用
  5. 用什么软件测试高考成绩,优志愿、知涯升学等志愿填报软件测评出来啦!最好用的是这个...
  6. 2021年秋招面经:上海禾赛提前批(FPGA设计)
  7. php如何ping域名的ip,使用PHP ping域名或IP
  8. Faster-Rcnn 网络训练医学乳腺DDSM图像不能预测到定位框问题及其训练问题
  9. 【PS】海报设计,滤镜
  10. 机器学习公开课笔记第一周