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、 全面的检查返回值、环境变量、输出输出参数
代码编写经常会涉及到延时处理,而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、 全面的检查返回值、环境变量、输出输出参数
相关文章推荐
- linux用户空间和内核空间的延时函数
- linux 用户空间 和 内核空间 延时函数
- linux 用户空间 和 内核空间 延时函数
- Linux中的延时函数 .
- Linux中的延时函数
- 转载_Linux内核延时研究与函数代码分析
- 5-3 Linux内核计时、延时函数与内核定时器【转】
- linux中的延时函数(部分)供初学者参考
- linux用户空间和内核空间延时函数
- 关于linux中的延时函数
- Linux中的延时函数
- Linux 内核延时函数
- linux 用户空间 和 内核空间 延时函数
- linux延时函数
- Linux中的延时函数
- linux和windows下,C/C++开发的延时函数,sleep函数
- 关于linux中的延时函数
- linux延时函数
- linux下的休眠与延时函数
- Linux中的延时函数