pzb19841116 发表于 2016-07-14 16:16

Linux下usleep函数求教

usleep函数不能用于秒级以上的延时
原因分析: 在某些系统中usleep接受的入参最大值必须小于1000000(即1秒)
规避措施:
1、用sleep函数替代
2、通过多次usleep完成
3、其他
说明:在Suse9/10上测试是没有问题的,但出于可移植性考虑,不要使用usleep作秒级以上的延时

————————————————————————————————————————————

小弟看博客读到这么一段描述,请问usleep参数大于1秒会出现什么情况呢?什么原因造成的?哪些系统会受影响啊,有没有高手深究过这个问题,点拨一下小弟呗

Tinnal 发表于 2016-07-14 23:17

本帖最后由 Tinnal 于 2016-07-14 23:29 编辑

谁告诉你的?

请看MAN手册,采用nanosleep就可以了。

pzb19841116 发表于 2016-07-15 06:33

回复 2# Tinnal


    我在实际应用中,的确碰到了啊。我知道nanosleep,但是之前的代码使用usleep实现的,不清楚为什么不能超过1s

nswcfd 发表于 2016-07-15 09:17

瞎猜的,它是posix库的(过时的)一部分,是man 3而不是man 2,
当它作为标准被制定出来的时候,也许标准委员会的人在想,大于1000000的休眠应该使用sleep和usleep的组合。 :lol

不知道在相关的标准文档里,有没有对这个限制做解释。
总之,这应该不是一个技术实现问题,而是一个标准的取舍问题。

Tinnal 发表于 2016-07-15 22:13

回复 3# pzb19841116


认同nswcfd的说法。应该仅仅是一个标准问题。实现代码是可以大于一秒的,见如下glibc代码:
https://github.com/lattera/glibc/blob/a2f34833b1042d5d8eeb263b4cf4caaea138c4ad/sysdeps/unix/sysv/linux/usleep.cint
usleep (useconds_t useconds)
{
struct timespec ts = { .tv_sec = (long int) (useconds / 1000000),
                       .tv_nsec = (long int) (useconds % 1000000) * 1000ul };

/* Note the usleep() is a cancellation point.But since we call
   nanosleep() which itself is a cancellation point we do not have
   to do anything here.*/
return __nanosleep (&ts, NULL);
}

nswcfd 发表于 2016-07-18 13:19

看到了关于cancellation point的注释,顺便提一个问题。

如果某个库函数是canellation point,通常需要做什么?
例如在这里,__naosleep的实现需要做什么?

需要在loop里插入一些类似于kernel里面test_need_resched之类的检查?
页: [1]
查看完整版本: Linux下usleep函数求教