精确延时的实现
来源:互联网 发布:暗夜尊影改装数据 编辑:程序博客网 时间:2024/05/11 09:26
大家平时写练习程序,包括网站上的范例程序,很多延时都直接用的 Sleep() 实现。这个延时有个缺点,那就是无法统计代码执行的时间。请看下图:
由图可以看到,使用 API 函数 Sleep() 的问题,就是会忽略掉程序的执行时间。很多时候,程序的执行时间是不固定的,所以这就导致使用 Sleep 的延时并不精确,即便 Sleep 使用相同的延时,也可能造成不同电脑上执行速度不同的结果。
图中,理想的延时函数会将程序的执行时间部分考虑进去,这样就可以实现很均匀的延时。下面讨论实现方法。
本次延时要从上次的延时结束开始计算,就必须要记录每次延时执行的具体时刻,而不仅仅是一个时间长度。所以,可以简单的使用 clock() 函数实现,代码如下:
// 精确延时函数(可以精确到 1ms,精度 ±1ms)// by yangw80<yw80@qq.com>, 2011-5-4void HpSleep(int ms){static clock_t oldclock = clock();// 静态变量,记录上一次 tickoldclock += ms * CLOCKS_PER_SEC / 1000;// 更新 tickif (clock() > oldclock)// 如果已经超时,无需延时oldclock = clock();elsewhile(clock() < oldclock)// 延时Sleep(1);// 释放 CPU 控制权,降低 CPU 占用率}
直接用函数 HpSleep 替换 Sleep 就可以很直观的看到效果。例如,《自由运动的点》这个程序,就是用的前述函数实现精确延时。
和 clock() 函数类似的还有 GetTickCount() 函数,clock() 的精度高一些,其精度取决于常量 CLOCKS_PER_SEC,通常在 1ms。根据微软 MSDN 的描述,GetTickCount() 的精度在 10ms~16ms 之间。
以上代码可以实现微秒级的延时。如果需要更高的精确度,可以使用多媒体定时器。做为范例,以下代码实现微秒级的延时,并封装成类:
// 代码名称:精确到微秒的延时类(基于多媒体定时器)// 代码编写:yangw80 <yw80@qq.com>// 最后修改:2011-5-4// 2013-11-2 修改为静态调用//#pragma once#include <windows.h>class MMTimer{private:static LARGE_INTEGER m_clk;// 保存时钟信息static LONGLONG m_oldclk;// 保存开始时钟和结束时钟static int m_freq;// 时钟频率(时钟时间换算率),时间差public:static void Sleep(int ms);};LARGE_INTEGER MMTimer::m_clk;LONGLONG MMTimer::m_oldclk;int MMTimer::m_freq = 0;// 延时void MMTimer::Sleep(int ms){if (m_oldclk == 0){QueryPerformanceFrequency(&m_clk);m_freq = (int)m_clk.QuadPart / 1000;// 获得计数器的时钟频率// 开始计时QueryPerformanceCounter(&m_clk);m_oldclk = m_clk.QuadPart;// 获得开始时钟}unsigned int c = ms * m_freq;m_oldclk += c;QueryPerformanceCounter(&m_clk);if (m_clk.QuadPart > m_oldclk)m_oldclk = m_clk.QuadPart;elsedo{::Sleep(1);QueryPerformanceCounter(&m_clk);// 获得终止时钟}while(m_clk.QuadPart < m_oldclk);}
看明白了前面的叙述,这个代码应该很容易就能看懂。
使用方法:将以上代码拷贝到新建的 MMTimer.h 中,然后在主程序中加上 #include "MMTimer.h",在需要 Sleep 的地方执行 MMTimer::Sleep 方法。
为了简单起见,只写了一个 .h 文件。更标准一些的做法,是将前述代码再分离出一个 MMTimer.cpp 文件,甚至改掉 MMTimer 这个名字,或者封装成库等等,这些就不再多说了,本文只想阐述一个方法。
来源:http://www.easyx.cn/skills/View.aspx?id=73
- 精确延时的实现
- stm32f051精确延时的实现
- 利用stm32f103的TIM2实现精确延时
- UCOS 的延时函数OSTimeDlyHMSM()实现精确延时 .
- UCOS 的延时函数OSTimeDlyHMSM()实现精确延时
- MSP430的精确延时
- STM32的精确延时
- 通过软件忙等进行精确延时的实现
- KEIL C 的精确延时
- IAR 的精确延时程序
- IAR的精确延时程序
- AVR 的精确延时程序
- 利用Keil调试精确实现软件延时
- for循环实现C语言精确延时
- 利用Keil精确实现软件延时
- for循环实现C语言精确延时
- STM32使用systick实现精确延时
- 怎样编写精确的延时函数
- 从K近邻算法、距离度量谈到KD树、SIFT+BBF算法
- POJ 2594--Treasure Exploration【二分图 && 最小路径覆盖 && 点可以重复走 && 传递闭包】
- NSInvocation的使用
- PS学习笔记-----恢复到画面初始打开状态:“F12键”
- hdu1054 Strategic Game(最小覆盖点-树形dp)
- 精确延时的实现
- ios真机调试 老是显示输入管理员的用户和密码
- 设计模式: 自己手动写一适配器和外观模式
- hdu 3371 Connect the Cities
- 如何使用Spark ALS实现协同过滤
- 菠萝蜜\菠萝蜜和榴莲有什么区别?
- NSInvocation使用
- Talking Small: Using Eclipse Paho's MQTT on BeagleBone Black and Raspberry Pi
- DMA控制器