《关于各种延时》由会员分享,可在线阅读,更多相关《关于各种延时(12页珍藏版)》请在金锄头文库上搜索。
1、关于各种延时在 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 接受一个指向一
2、个 struct timespec 对象的指针 作为参数,它可以表示毫微秒(nanosecond,十亿分之一秒)的时间。然而, 了解 Linux 内核的工作细节后可知,nanosleep 所提供的真正精确度是 10 毫秒 比 sleep 提供的要精确。这个附加的精确度非常有用,比如说,可以根为 反复进行的任务设置更短的间隔。 struct timespec 由两部分构成:tv_sec 表示整秒数部分;tv_nsec 则表示毫微秒。 tv_nesc 的值必须小于 109。 nanosleep 相比 sleep 具有另一个优点。与 sleep 相同,nanosleep 调用可以被信 号中断,这是
3、errno 将被设置为 EINTR 而调用将返回 -1。但是,nanosleep 的第二个参数,另一个指向 struct timespec 对象的指针,如果不为 NULL 则在 这种情况下它将被写入剩余的时间(这就是所请求的睡眠时间和实际睡眠时间 的差)。这使重新开始睡眠变的很容易。 头文件 。以下是内核中的:1.udelay(); mdelay(); ndelay();实现的原理本质上都是忙等待,ndelay 和 mdelay 都是通过 udelay 衍生出来的,我们使用这些函数的实现往往会碰到编译器的 警告 implicit declaration of function udelay,这
4、往往是由于头文件的使用不当造 成的。在 include/asm-?/delay.h 中定义了 udelay(),而在 include/linux/delay.h 中定义了 mdelay 和 ndelay.udelay 一般适用于一个比较小的 delay,如果你填的数大于 2000,系统会认为你这个是一个错误的 delay 函数, 因此如果需要 2ms 以上的 delay 需要使用 mdelay 函数。2.由于这些 delay 函数本质上都是忙等待,对于长时间的忙等待意味这无谓的耗 费着 cpu 的资源,因此对于毫秒级的延时,内核提供了 msleep,ssleep 等函数, 这些函数将使得调用它
5、的进程睡眠参数指定的时间。那么,在 Windows 中呢:1)我们很快想到 Sleep();头文件然后再 VC+中,找到了一篇不错的文章,转自这里,内容如下:方法一:VC 中的 WM_TIMER 消息映射能进行简单的时间控制。首先调用函数 SetTimer()设置定时 间隔,如 SetTimer(0,200,NULL)即为设置 200ms 的时间间 隔。然后在应用程序中增加定时响应函数 OnTimer(),并在该函数中添加响应 的处理语句,用来完成到达定时时间的操作。这种定时方法非常 简单,可以实 现一定的定时功能,但其定时功能如同 Sleep()函数的延时功能一样,精度非常 低,最小 计时精
6、度仅为 30ms,CPU 占用低,且定时器消息在多任务操作系统 中的优先级很低,不能得到及时响 应,往往不能满足实时控制环境下的应用。 只可以用来实现诸如位图的动态显示等对定时精度要求不高的情况。如示例工 程中的 Timer1。 方法 二:VC 中使用 sleep()函数实现延时,它的单位是 ms,如延时 2 秒,用 sleep(2000)。精度非常 低,最小计时精度仅为 30ms,用 sleep 函数的不利处在 于延时期间不能处理其他的消息,如果时间太 长,就好象死机一样,CPU 占 用率非常高,只能用于要求不高的延时程序中。如示例工程中的 Timer2。 方法三:利用 COleDateTi
7、me 类和 COleDateTimeSpan 类结合 WINDOWS 的 消息处理过程来实现秒级延时。如示例工程中的 Timer3 和 Timer3_1。以下是 实现 2 秒的延时代码: COleDateTime start_time = COleDateTime:GetCurrentTime(); COleDateTimeSpan end_time= COleDateTime:GetCurrentTime()-start_time; while(end_time.GetTotalSeconds(); #include ; #include ; #include ; #include ; #i
8、nclude ; #include ; #include ;#define PRINT_USEAGE fprintf(stderr,“n Usage: %s usec “,argv0); fprintf(stderr,“nn“); int main (int argc, char *argv) unsigned int nTimeTestSec = 0; /* sec */ unsigned int nTimeTest = 0; /* usec */ struct timeval tvBegin; struct timeval tvNow; int ret = 0; unsigned int
9、nDelay = 0; /* usec */ fd_set rfds;struct timeval tv; int fd = 1; int i = 0; struct timespec req; unsigned int delay20 = 500000, 100000, 50000, 10000, 1000, 900, 500, 100, 10, 1, 0 ; int nReduce = 0; /* 误差 */#if 0 if (argc 2)PRINT_USEAGE;exit (1); nDelay = atoi (argv1); #endiffprintf (stderr, “%18s%
10、12s%12s%12sn“, “function“, “time(usec)“, “realTime“,“reduce“); fprintf (stderr,“- -n“);for (i = 0; i 20; i+)if (delayi = 0)break;nDelay = delayi;/* test usleep */gettimeofday (ret = usleep (nDelay);if (-1 = ret)fprintf (stderr, “ usleep error . errno=%d %sn“, errno,strerror (errno);gettimeofday (nTi
11、meTest =(tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec -tvBegin.tv_usec;nReduce = nTimeTest - nDelay;fprintf (stderr, “t usleep %8u %8u %8dn“, nDelay, nTimeTest,nReduce);/* test nanosleep */gettimeofday (req.tv_sec = nDelay / 1000000;req.tv_nsec = (nDelay % 1000000) * 1000;ret = nanosleep
12、 (if (-1 = ret)fprintf (stderr, “t nanosleep %8u not supportn“, nDelay);elsegettimeofday (nTimeTest =(tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec -tvBegin.tv_usec;nReduce = nTimeTest - nDelay;fprintf (stderr, “t nanosleep %8u %8u %8dn“, nDelay,nTimeTest, nReduce);/* test select */gettim
13、eofday (FD_ZERO (FD_SET (fd, tv.tv_sec = 0;tv.tv_usec = nDelay;ret = select (0, NULL, NULL, NULL, if (-1 = ret)fprintf (stderr, “ select error . errno=%d %sn“, errno,strerror (errno);gettimeofday (nTimeTest =(tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec -tvBegin.tv_usec;nReduce = nTimeTe
14、st - nDelay;fprintf (stderr, “t select %8u %8u %8dn“, nDelay, nTimeTest,nReduce);return 0; - - -测试 IBM AIX 3.4 单 CPUsleep 可以在多线程中使用,只阻塞本线程,不影响所属进程中的其 它线程不支持 nanosleep支持 usleep 和 select 以下采用 gettimeofday 对 usleep 和 select 的实际精确情况进行 测试分析function time(usec) realTime reduce -usleep 500000 500026 26nanosleep 500000 not supportselect 500000 500026 26usleep 100000 100021 21nanosleep 100000 not supportselect 100000 100025 25usleep 50000 50021 21nanosleep 50000 not supportselect 50000 50107 107usleep