您的位置:首页 > 运维架构 > Linux

Linux延时函数

2013-08-28 20:19 288 查看
前言

代码编写经常会涉及到延时处理,而Linux环境下系统最常用的延时函数不过如下几个sleep/usleep/nanosleep,分别提供秒级、微秒级、纳秒级延时功能,这几个函数我们几乎天天都在使用,但我们是否准确安全的使用了他们?

先来看一下几个函数的原型:

unsigned int sleep(unsigned int seconds);

int usleep(useconds_t usec);

int nanosleep(const struct timespec *req, struct timespec *rem);

useconds_t在linux中的定义就是unsigned int

struct timespec {

time_t tv_sec; /* seconds */

long tv_nsec; /* nanoseconds */

};

1、 sleep函数可能提前返回,即延时时间不足seconds秒

原因分析:sleep函数可能被信号中断而提前返回

规避措施:判断sleep的返回值,只有返回0时才表示完成预期的延时,否则返回剩余的秒数。所以请检查一下您的代码中是否判断了sleep的返回值?

2、 usleep/nansleep函数成功返回时其延时时间可能大于入参指定的时间

原因分析:usleep函数手册中明确标示usleep调用至少挂起进程usec微秒,导致进程挂起时间变长的原因是:

1、 函数调用的开销

2、 系统调度开销

3、 系统定时器的精度

规避措施:

1、 一定要判定usleep的返回值,仅当返回0表示成功

2、 在时间精度要求比较高的场合不建议使用usleep函数

3、 usleep函数不能用于秒级以上的延时

原因分析: 在某些系统中usleep接受的入参最大值必须小于1000000(即1秒)

规避措施:

1、 用sleep函数替代

2、 通过多次usleep完成

3、 其他

说明:在Suse9/10上测试是没有问题的,但出于可移植性考虑,不要使用usleep作秒级以上的延时

4、nanosleep函数延时存在多种情况,需要根据返回值/errno/输出变量综合判断

情况1延时时间大于或是等于预期时间(绝大部分情况下),返回0

情况2延时时间小于预期时间,返回-1

情况2.1 errno为EINTR表示函数提前返回,此时可读取第2个参数的获取剩余时间

情况2.2 errno为EINVAL表示第一个入参req.tv_nsec取值超出范围[0, 999,999,999]

后记

简简单单一个延时函数的使用,就存在这么多需要关注的细节,看来千里之堤毁于蚁穴并非危言耸听(我们至少有70%代码中没有判断延时函数的返回值)。每个健壮的系统、每项高精尖的技术肯定离不开这些细节的处理。对于软件开发而言,要处理好这些细节,简言之就是标准动作做标准(这些在编程规范中都有要求)

1、 了解你的系统、接口、库函数,仔细的查看帮助文档、手册

2、 全面的检查返回值、环境变量、输出输出参数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: