当前位置: 首页 > 编程日记 > 正文

VC中基于 Windows 的精确定时

方式一:VC中的WM_TIMER消息映射能进行简单的时间控制。首先调用函数SetTimer()设置定时 间隔,如SetTimer(0,200,NULL)即为设置200ms的时间间隔。然后在应用程序中增加定时响应函数 OnTimer(),并在该函数中添加响应的处理语句,用来完成到达定时时间的操作。这种定时方法非常 简单,可以实现一定的定时功能,但其定时功能如同Sleep()函数的延时功能一样,精度非常低,最小 计时精度仅为30ms,CPU占用低,且定时器消息在多任务操作系统中的优先级很低,不能得到及时响 应,往往不能满足实时控制环境下的应用。只可以用来实现诸如位图的动态显示等对定时精度要求不高的情况。如示例工程中的Timer1。
  方式二:VC中使用sleep()函数实现延时,它的单位是ms,如延时2秒,用sleep(2000)。精度非常 低,最小计时精度仅为30ms,用sleep函数的不利处在于延时期间不能处理其他的消息,如果时间太 长,就好象死机一样,CPU占用率非常高,只能用于要求不高的延时程序中。如示例工程中的Timer2。
  方式三:利用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型,表示以ms为单位的计算机启动后经历的时间间隔。精度比WM_TIMER消息映射高,在较 短的定时中其计时误差为15ms,在较长的定时中其计时误差较低,如果定时时间太长,就好象死机一样,CPU占用率非常高,只能用于要求不高的延时程序中。如示例工程中的Timer4和Timer4_1。下列代码可以实现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)函数未定义。由于使用该 函数是通过查询的方式进行定时控制的,所以,应该建立定时循环来进行定时事件的控制。如示例工程中的Timer5和Timer5_1。
  方式六:使用多媒体定时器timeSetEvent()函数,该函数定时精度为ms级。利用该函数可以实现周期性的函数调用。如示例工程中的Timer6和Timer6_1。函数的原型如下:
    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及其后续版本使用的精确时间函数,并要求计算机从硬件上支持精确定时器。如示例工程中的Timer7、Timer7_1、Timer7_2、Timer7_3。
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);
  其定时误差不超过1微秒,精度与CPU等机器配置有关。 下面的程序用来测试函数Sleep(100)的精确持续时间:
    LARGE_INTEGER litmp;
    LONGLONG QPart1,QPart2;
    double dfMinus, dfFreq, dfTim;
    QueryPerformanceFrequency(&litmp);
    dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率
    QueryPerformanceCounter(&litmp);
    QPart1 = litmp.QuadPart;// 获得初始值
    Sleep(100);
    QueryPerformanceCounter(&litmp);
    QPart2 = litmp.QuadPart;//获得中止值
    dfMinus = (double)(QPart2-QPart1);
    dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒  
  由于Sleep()函数自身的误差,上述程序每次执行的结果都会有微小误差。下列代码实现1微秒的精确定时:
    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.000001);
其定时误差一般不超过0.5微秒,精度与CPU等机器配置有关。

转载于:https://www.cnblogs.com/cy163/archive/2006/10/18/532867.html

相关文章:

VMware虚拟机安装之后,打开时找不到启动Centos的界面

#VMware虚拟机安装之后&#xff0c;打开时找不到启动Centos的界面 只要在VMware中打开查看–自定义–库&#xff0c;之后就看到自己已经创建好的虚拟机系统 我也是因为自己不小心上次关机之前把左边那个窗口关闭了

service iptables status无法执行,报错

1. service iptables status 结果为edirecting to /bin/systemctl stop iptables.service Failed to stop iptables.service: Unit iptables.service not load 3.安装Iptables-services 在root 用户下&#xff0c;执行指令 yum installl iptables-services3.设置开机启动 …

Qt5的cmake文件位置

D:\APICenter\Qt\Qt5.8.0\5.8\msvc2015\lib\cmake\Qt5\Qt5Config.cmake转载于:https://www.cnblogs.com/coolbear/p/7149079.html

2018-12-2

博客第一天&#xff0c;今天申请通过&#xff0c;我以为我上个星期就已经申请通过了。没想到博客还得申请一下&#xff0c;哈哈&#xff0c;今天终于成功了&#xff0c;加油哦转载于:https://www.cnblogs.com/h-wei/p/10056227.html

重载、重写和隐藏

重载、重写和隐藏 重载、重写和隐藏是很容易混淆的类似概念。虽然所有这三种技术都使您得以创建同名的成员&#xff0c;但它们之间有一些重要的差异。 重载的成员用于提供属性或方法的不同版本&#xff0c;这些版本具有相同名称但是接受不同数量的参数或者接受不同数据类型的参…

[整理] - Relational Engine之UMS Internals

SQL Server 6.5使用Windows的调度处理管理多线程&#xff0c;和其它Windows应用程序一样&#xff0c;它使用Windows标准API&#xff0c;没有用到任何隐藏API&#xff0c;这使得 SQL Server的工作线程同其它多线程Windows程序完全一样&#xff0c;没有任何特殊的优先级&#xff…

跟踪workflow instance 状态

场景是这样的: 1.workflowruntime启动了持久化和监听服务 2.workfllowruntime创建多个实例,并启动,一些会长时间延时,一些会中途暂停,会不同的执行状态(业务状态) 3.另有一winform控制台,有个表格,刷新显示每个实例的信息,包括业务状态--比如创建,运行,挂起等 4.通过workflowru…

尝试Java,从入门到Kotlin(上)

之前一直使用C#开发&#xff0c;最近由于眼馋Java生态环境&#xff0c;并借着工作服务化改造的契机&#xff0c;直接将新项目的开发都转到Java上去。积攒些Java开发经验&#xff0c;应该对.NET开发也会有所启发和益处。 从理论上说&#xff0c;Java和C#语言差别不大&#xff0c…

Centos7状态下查看防火墙状态及修改服务端口

查看当前主机监听哪些服务端口 netstat -telunp查看防火墙firewall开放端口 fiewall-cmd --list-ports增加对外开放的端口 firewall-cmd --zonepublic --add-port8080/tcp --permanent扩充)关闭某个端口 firewall-cmd --permanent --remove-port8080/tcp重启防火墙 firewa…

VMWare中CentOS7 设置固定IP且能够访问外网

最近搭建kubernetes集群环境时遇到一个问题&#xff0c;CentOS7在重启后IP发生变化导致集群中etcd服务无法启动后集群环境变得不可用&#xff0c;针对这种情况&#xff0c;必须要对CentOS7设置固定IP且可以访问外网&#xff08;下载镜像用&#xff09;。 首先关闭VMware的DHCP&…

使用ASP.NET Atlas编写显示真实进度的ProgressBar(进度条)控件

当后台在进行某些长时间的操作时&#xff0c;如果能在页面上提供一个显示真实进度的进度条&#xff0c;而不是让用户不知情的等待或是从前的那些简单的估计&#xff0c;将是一个非常难得的出彩之处。现在使用ASP.NET Atlas完全有可能做到这些。这篇文章将讨论如何完成这一功能并…

初始化Mysql系统报错,begin failesd--conpilation aborted at scripts........

在编译安装Mysql之后进行初始化&#xff0c;但是出现了报错 初始化mysql scripts/mysql_install_db --basedir/usr/local/mysql --datadir/usr/local/mysql/data --usermysqlBEGIN failed–compilation aborted at scripts/mysql_install_db line 42 从报错的结果中看出Can…

asp.net Core多环境读取Json

IHostingEnviroment 获取环境相关洗洗 IsDevelopment()、IsStaging()、IsProduction() 分别为:开发、准生产、生产环境 IsEnviroment("Uat") 自定义环境,比如自定义Uat环境 新建: appsettings.Uat.json文件 {"Enviroment": "Uat" }Controller文件…

Microsoft Anti-Cross Site Scripting Library V1.5 发布了

Microsoft Anti-Cross Site Scripting Library V1.5 发布了 微软反跨站攻击脚本库 v1.5。此下载包含Microsoft Application Security Anti-Cross Site Scripting Library的分发组件.Anti-Cross Site Scripting Library可以为网站开发人员提供基于Web应用防护,以抵御源自 Cross-…

nodejs高版本转低版本

需要安装 第一步: npm install --save-dev babel-register npm install --save-dev babel-polyfill //由于只安装babel-register,无法解决低版本问题所以需要这个 npm install --save-dev babel-preset-latest //高版本到低版本js的一条路需要指定babelrc 最后需要创建文件: .b…

替换不文明词语和非法字符

//替换不文明词语和非法字符stringStrReplaceSk(stringcheckstr){ string repstr""; if(Application["repstr"] ! null) { repstr Application["repstr"].ToString(); } else { Uri myUri new Uri("http:…

BZOJ4568: [Scoi2016]幸运数字(线性基 倍增)

题意 题目链接 Sol 线性基是可以合并的 倍增维护一下 然后就做完了&#xff1f;&#xff1f; 喵喵喵&#xff1f; // luogu-judger-enable-o2 #include<bits/stdc.h> #define LL long long using namespace std; const int MAXN 2e4 10, B 60; inline LL read() {cha…

centos7给MySQL配置环境变量

centos7给MySQL配置环境变量 配置好了环境变量&#xff0c;就可以不用每次想要使用mysql时都要到/usr/local/mysql/bin&#xff0c;所以需要配置以下环境变量 编辑配置文件&#xff0c;加入环境变量 Vi /etc/profile在文件后面加上环境变量 export PATH$PATH:/usr/local/mys…

SQL2000联机丛书:使用和维护数据仓库

本次摘录 来源于SQL2000联机丛书中 创建和使用数据仓库概述为的是对数据仓库有个概观的认识使用数据仓库SQL 查询 --------- 最终用户很少使用结构化查询语言 (SQL) 查询直接访问数据仓库数据。 分析 SQL 查询很复杂&#xff0c;必须具有数据库专…

activiti自己定义流程之Spring整合activiti-modeler5.16实例(四):部署流程定义

注&#xff1a;&#xff08;1&#xff09;环境搭建&#xff1a;activiti自己定义流程之Spring整合activiti-modeler5.16实例&#xff08;一&#xff09;&#xff1a;环境搭建&#xff08;2&#xff09;创建流程模型&#xff1a;activiti自己定义流程之Spring整合activiti-model…

[rails] 我的订餐系统 -- 小试ruby on rails(转)

前言 近期在java社区中一种新的脚本语言ruby,及用ruby开发的一个wab框架 rails也热闹了起来.引起了不少的java开发人员的关注&#xff0e; 本人平时还是很少接触脚本语言方面东东,看到相关的评论例如: "习惯约定优于配置" -- 那样就用象java那样麻烦且繁杂…

DateReader,DateAdapter,DateSet和SqlCommand的基本使用方法

1usingSystem;2usingSystem.Data;3usingSystem.Data.SqlClient;45namespaceDemo36{ 7 /**//// <summary> 8 /// Class1 的摘要说明。 9 /// </summary>10 class Class111 {12 /**//// <summary>13 /// 应用程序的主入口点。14 /// </summary>15 [S…

JAVA实现长连接(含心跳检测)Demo

实现原理&#xff1a; 长连接的维持&#xff0c;是要客户端程序&#xff0c;定时向服务端程序&#xff0c;发送一个维持连接包的。 如果&#xff0c;长时间未发送维持连接包&#xff0c;服务端程序将断开连接。客户端&#xff1a; Client通过持有Socket的对象&…

java开发环境变量配置-JDK11-(win10),重启之后环境变量配置失效的解决办法

win10安装jdk11及环境变量配置 如果你之前已经安装过java的老版本的话&#xff0c;建议先卸载一下&#xff0c;同时删除掉环境变量的配置&#xff0c;这样比较容易一次性成成功&#xff0c;直接到设置里面应用程序找到java卸载就好 下载JDK11 直接附上官网链接&#xff1a;htt…

Activity启动流程图

转载于:https://www.cnblogs.com/dikeboy/p/10064610.html

sql 70-229 考试样题(1)

转&#xff1a;1&#xff0e;你是一数据公司的数据库开发者&#xff0c;你创建了一个用来存储15个不同高校运动会统计表的数据库。这些信息将被用在50家公司的网页设置上。每个公司的WEB设置以不同的格式来安排和显示这些统计表。你需要组装这些数据传送到这些公司去&#xff0…

HDU 5616 Jam's balance(01背包)

题目网址&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid5616 题目&#xff1a; Jams balance Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1810 Accepted Submission(s): 754 Problem Description…

datagrid DataFormatString

DataFormatString格式字符串 DataFormatString"{0:格式字符串}" 在DataFormatString 中的 {0} 表示数据本身&#xff0c;而在冒号后面的格式字符串代表所们希望数据显示的格式&#xff1b; 数字、货币格式&#xff1a;在指定的格式符号后可以指定小数所要显示的位数…

HashMap 和 Hashtable 的 6 个区别,最后一个没几个人知道!

HashMap 和 Hashtable 是 Java 开发程序员必须要掌握的&#xff0c;也是在各种 Java 面试场合中必须会问到的。 但你对这两者的区别了解有多少呢&#xff1f; 现在&#xff0c;栈长我给大家总结一下&#xff0c;或许有你不明朗的地方&#xff0c;在栈长的指点下都会拨开迷雾见晴…

自学笔记——Python内置的处理字符串的函数

序号函数描述1capitalize() 字符串的首字母变为大写2center&#xff08;width, fillchar&#xff09; 返回原来的字符串&#xff08;居中&#xff09;&#xff0c;并以空格填充至特定长度的字符串3count( str ,beg 0, end len(string) )计算出str在字符串中出现的字数&#x…