admin管理员组

文章数量:1530842

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

本文标签: 时间延时函数实现睡眠