admin管理员组文章数量:1567263
2024年5月18日发(作者:)
关于各种延时
在Linux中,如果是应用层下的一些应用,我们可以:
1)调用unsigned int sleep(unsigned int second);函数去定时,这个时候它是秒级的;
头文件为
2)调用int usleep(useconds_t);函数去定时,这个时候它是微秒级的;头文件为
3)调用高精度睡眠int nanosleep(const struct timespec * rep, struct timespec *rem);
是一个相比标准UNIX 的sleep 调用具有更高高精度的版本。和普通的sleep 调
用计算整秒数不同,nanosleep 接受一个指向一个struct timespec 对象的指针作
为参数,它可以表示毫微秒(nanosecond,十亿分之一秒)的时间。然而,了解
Linux 内核的工作细节后可知,nanosleep 所提供的真正精确度是10毫秒——比
sleep 提供的要精确。这个附加的精确度非常有用,比如说,可以根为反复进行
的任务设置更短的间隔。
struct timespec 由两部分构成:tv_sec 表示整秒数部分;tv_nsec 则表示毫微秒。
tv_nesc 的值必须小于109。
nanosleep 相比sleep具有另一个优点。与sleep 相同,nanosleep 调用可以被信
号中断,这是errno 将被设置为 EINTR 而调用将返回 -1。但是,nanosleep 的
第二个参数,另一个指向struct timespec 对象的指针,如果不为 NULL 则在这
种情况下它将被写入剩余的时间(这就是所请求的睡眠时间和实际睡眠时间的
差)。这使重新开始睡眠变的很容易。 头文件
以下是内核中的:
(); mdelay(); ndelay();实现的原理本质上都是忙等待,ndelay和mdelay都
是通过udelay衍生出来的,我们使用这些函数的实现往往会碰到编译器的 警告
implicit declaration of function 'udelay',这往往是由于头文件的使用不当造成的。
在include/asm-???/delay.h中定义了udelay(),而在 include/linux/delay.h中定
义了mdelay和一般适用于一个比较小的delay,如果你填的数大于
2000,系统会认为你这个是一个错误的delay函数,因此如果需要2ms以上的
delay需要使用mdelay函数。
2.由于这些delay函数本质上都是忙等待,对于长时间的忙等待意味这无谓的耗
费着cpu的资源,因此对于毫秒级的延时,内核提供了msleep,ssleep等函数,
这些函数将使得调用它的进程睡眠参数指定的时间。
那么,在Windows中呢:
1)我们很快想到Sleep();头文件
然后再VC++中,找到了一篇不错的文章,转自这里,内容如下:
方法一: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_alSeconds()< 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);
版权声明:本文标题:关于各种延时 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1716046744a483437.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论