首页
登录 | 注册

Windows下用MFC实现微秒级延时

   一帮情况可以使用Sleep()函数来实现延时,但Windows不是实时的,是操作系统来分配处理器给多个线程的,而不会线程一直拥有处理器的使用权。比如延时50ms,不论采用什么方式来延时,50ms以后,操作系统未必就正好把处理器分配给这个线程使用。
   使用一个Sleep(50),这下这个线程就暂停了,50ms以内操作系统就不会把处理器给这个线程用,50ms以后这个线程要求处理器,操作系统才会可能给他分配,但是仅仅是可能,也有可能这时候有一个优先级更高的线程也要用处理器,操作系统就不一定给他。可能等到这个更高优先级的线程用完了,这时候已经过了55ms了,就不是精确的了。

   在Windows平台下,常用的计时器还有另外两种,一种是timeGetTime多媒体计时器,它可以提供毫秒级的计时。但这个精度对很多应用场合而言还是太粗糙了。另一种是QueryPerformanceCount计数器,随系统的不同可以提供微秒级的计数。对于实时图形处理、多媒体数据流处理、或者实时系统构造的程序员,善用QueryPerformanceCount/QueryPerformanceFrequency是一项基本功。

  可以使用 QueryPerformanceCount/QueryPerformanceFrequency实现微秒级的延时,例子如下:

void DelayUs(double uDelay)
{
	LARGE_INTEGER litmp;
    LONGLONG QPart1,QPart2;
  
      double dfMinus,dfFreq,dfTim; //定义变量
      
      /*
         Pointer to a variable that the function sets, in counts per second, to the current performance-counter frequency. 
         If the installed hardware does not support a high-resolution performance counter, 
         the value passed back through this pointer can be zero. 
 
     */
     QueryPerformanceFrequency(&litmp); //获取当前电脑的时钟频率
 
     dfFreq = (double)litmp.QuadPart;
 
     /*
         Pointer to a variable that the function sets, in counts, to the current performance-counter value. 
     */
     QueryPerformanceCounter(&litmp); //获取延时前的CPU执行次数
 
     QPart1 = litmp.QuadPart;
     do
     {
           QueryPerformanceCounter(&litmp);//获取延时后的CPU执行次数
         QPart2 = litmp.QuadPart;
         dfMinus = (double)(QPart2-QPart1);//延时后的CPU执行次数 减去  延时前的CPU执行次数
		 if (dfMinus < 0)
			 break;
         dfTim = dfMinus/dfFreq * 1000000;
		 //dfTim = dfMinus/dfFreq;
      }while(dfTim< uDelay); //延时时间小于预定值,继续进行延时
   
}

  对延时函数进行测试:

#include <stdio.h>
#include <Windows.h>

void DelayUs(double uDelay)
{
	LARGE_INTEGER litmp;
    LONGLONG QPart1,QPart2;
  
      double dfMinus,dfFreq,dfTim;
      
      /*
         Pointer to a variable that the function sets, in counts per second, to the current performance-counter frequency. 
         If the installed hardware does not support a high-resolution performance counter, 
         the value passed back through this pointer can be zero. 
 
     */
     QueryPerformanceFrequency(&litmp);
 
     dfFreq = (double)litmp.QuadPart;
 
     /*
         Pointer to a variable that the function sets, in counts, to the current performance-counter value. 
     */
     QueryPerformanceCounter(&litmp);
 
     QPart1 = litmp.QuadPart;
     do
     {
           QueryPerformanceCounter(&litmp);
         QPart2 = litmp.QuadPart;
         dfMinus = (double)(QPart2-QPart1);
		 if (dfMinus < 0)
			 break;
         dfTim = dfMinus/dfFreq * 1000000;
		 //dfTim = dfMinus/dfFreq;
      }while(dfTim< uDelay);
   
}

void main()
{
LARGE_INTEGER t1, t2, tc;
QueryPerformanceFrequency(&tc);
printf("Frequency: %u \n", tc.QuadPart);
QueryPerformanceCounter(&t1);
//Sleep(1000);
DelayUs(20000);
QueryPerformanceCounter(&t2);
printf("Begin Time: %u \n", t1.QuadPart);
printf("End Time: %u \n", t2.QuadPart);
printf("Lasting Time: %u \n",( t2.QuadPart- t1.QuadPart));
}

程序执行结果:

 Windows下用MFC实现微秒级延时

机器的CPU频率为3117382Hz

延时前CPU执行次数为:985262162

延时后CPU执行次数为:985324514

延时函数总共耗费CPU执行次数为:62352

 实际延时时间为:62352/3117382 ≈0.02000139860947423190356523518773

延时误差在0.2微秒以内,基本能达到微秒级的延时要求。

 


相关文章

  • 对话阿里云Alex Chen:下一代存储应如何面对云转型?
    数字经济"乘云而上". 十年前,阿里云开始自主研发云计算操作系统飞天之路,开启了中国云时代: 十年后,阿里云在中国市场份额超过2-8名总和,培育了整个中国云计算市场,数字经济在云上蓬勃发展. 十年前,EMC.NetApp ...
  • 前端基础---JS基础
    背景介绍 Javascript 是一种运行在客户端的脚本语言 应用场景: 1.网页特效 2.服务端开发(Node.js) 3.命令行工具(Node.js) 4.桌面程序(Elextron) 5.APP(Cordova) 6.控制硬件-物联网 ...
  • 云原生的新思考,为什么容器已经无处不在了
    4月24日,中国信息通信研究院主办的首届云原生产业大会在北京举行,在<云原生数字引领未来>的主题演讲中,阿里云容器服务总监易立表示:"云原生不但可以很好的支持互联网应用,也在深刻影响着新的计算架构.新的智能数据应用.以 ...
  • Redis radix tree源码解析
    Redis实现了不定长压缩前缀的radix tree,用在集群模式下存储slot对应的的所有key信息.本文将详述在Redis中如何实现radix tree. 核心数据结构 raxNode是radix tree的核心数据结构,其结构体如下代 ...
  • 嗯...这个问题十分不好回答啊(捋下鱼须).闲鱼作为flutter领域的先驱者,以及fish_redux.flutter_boost等当红flutter库的作者,当然是欢迎广大的开发者多多使用flutter相关技术栈 逃~:).咳咳,不过呢 ...

2019 jeepshoe.net webmaster#jeepshoe.net
13 q. 0.378 s.
京ICP备10005923号