小记——linux睡眠

1. 用于睡眠最基本的函数是sleep,相信大家已经耳熟能详了。

#include <unistd.h>
unsigned int sleep (unsigned int seconds);
这个函数的睡眠单位是秒,函数成功时返回0,当被信号中断睡眠时,返回值为还没有睡眠的时间。

2. Sleeping with Microsecond Precision

微秒级别的睡眠

/* BSD version */
#include <unistd.h>
void usleep (unsigned long usec);
/* SUSv2 version */
#define _XOPEN_SOURCE 500
#include <unistd.h>
int usleep (useconds_t usec);
A successful call to usleep() puts the invoking process to sleep for usec microseconds. Unfortunately, BSD and the Single UNIX Specification disagree on the prototype of the
function. The BSD variant receives an unsigned long and has no return value. The SUS variant, however, defines usleep() to accept a useconds_t type and return an int. Linux
follows SUS if _XOPEN_SOURCE is defined as 500 or higher. If _XOPEN_SOURCE is undefined or set to less than 500, Linux follows BSD.
Due to the differences between the conflicting prototypes and the fact that some Unix systems may support one or the other, but not both, it is wise never to explicitly include the useconds_t type in your code. For maximum portability, assume that the parameter is an unsigned int, and do not rely on usleep()’s return value:
void usleep (unsigned int usec);
Usage is then:
unsigned int usecs = 200;
usleep (usecs);


3. Sleeping with Nanosecond Resolution

#define _POSIX_C_SOURCE 199309
#include <time.h>
int nanosleep (const struct timespec *req, struct timespec *rem);
A successful call to nanosleep() puts the invoking process to sleep for the time specified by req and then returns 0. On error, the call returns −1 and sets errno appropriately. If a signal interrupts the sleep, the call can return before the specified time has elapsed. In that case, nanosleep() returns −1, and sets errno to EINTR. If rem is not NULL, the function places the remaining time to sleep (the amount of req not slept) in rem. The program may then reissue the call, passing rem for req.

4. 睡眠的高级接口

#include <time.h>
int clock_nanosleep (clockid_t clock_id,
int flags, const struct timespec *req, struct timespec *rem);
这个接口可用以睡眠到绝对时间或者相对时间。

The difference lies in the clock_id and flags parameters. The former specifies the time source to measure against. Most time sources are valid, although you cannot specify the CPU clock of the invoking process (e.g., CLOCK_PROCESS_CPUTIME_ID); doing so would make no sense because the call suspends execution of the process, and thus the process time stops increasing.
What time source you specify depends on your program’s goals for sleeping. If you are sleeping until some absolute time value, CLOCK_REALTIME may make the most sense. If you are sleeping for a relative amount of time, CLOCK_MONOTONIC definitely is the ideal time source.
The flags parameter is either TIMER_ABSTIME or 0. If it is TIMER_ABSTIME, the value specified by req is treated as absolute and not relative.
同时这个接口还可以解决竞态条件问题。


5. 兼容的睡眠接口

#include <sys/select.h>
int select (int n,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout);
USAGE:

struct timeval tv = { .tv_sec = 0,
.tv_usec = 757 };
/* sleep for 757 us */
select (0, NULL, NULL, NULL, &tv);
If portability to older Unix systems is a concern, using select() may be your best bet.

最后:

使用sleep类函数是无法精准睡眠的,而使用select()函数进行睡眠确可以获得更大的睡眠准度,这是经验教训。在现代的操作系统中,秒级精度的睡眠时间理论上可以达到的,但笔者一者有个疑问,受到硬件的限制,像微秒(10^-6秒)和纳秒(10^-9秒)的精确度应该是无法达到的,那么这linux系统下为什么又会设计有睡眠微秒和纳秒的时间呢?它们是如何实现的?运行的效果又是如何呢?如果有谁知道答案或者以后知道答案,请不吝留下您的评论呀!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一尺丈量

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值