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

小记——linux睡眠

2016-07-21 15:31 267 查看
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系统下为什么又会设计有睡眠微秒和纳秒的时间呢?它们是如何实现的?运行的效果又是如何呢?如果有谁知道答案或者以后知道答案,请不吝留下您的评论呀!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: