NANOSLEEP - Linux手册页

时间:2019-08-20 17:59:01  来源:igfitidea点击:

Linux程序员手册 第2部分
更新日期: 2017-09-15

名称

nanosleep-高分辨率睡眠

语法

#include <time.h>
int nanosleep(const struct timespec *req, struct timespec *rem);

glibc的功能测试宏要求(请参阅feature_test_macros(7)):

nanosleep():_POSIX_C_SOURCE> = 199309L

说明

nanosleep()暂停调用线程的执行,直到至少经过* req中指定的时间,或者传递的信号触发了调用线程中的处理程序的调用或终止了该过程。

如果调用被信号处理程序中断,则nanosleep()返回-1,将errno设置为EINTR,并将剩余时间写入rem指向的结构中,除非rem为NULL。然后,可以使用* rem的值再次调用nanosleep()并完成指定的暂停(但请参见"注释")。

结构timespec用于以纳秒精度指定时间间隔。定义如下:

struct timespec {
    time_t tv_sec;        /* seconds */
    long   tv_nsec;       /* nanoseconds */
};

纳秒字段的值必须在0到999999999之间。

sleep(3)和usleep(3)相比,nanosleep()具有以下优点:它为指定睡眠间隔提供了更高的分辨率; POSIX.1明确指定它不与信号交互;它使恢复被信号处理程序中断的睡眠的任务变得更加容易。

返回值

在成功睡眠达到请求的时间间隔后,nanosleep()返回0。如果调用被信号处理程序中断或遇到错误,则返回-1,并设置errno表示错误。

错误说明

EFAULT
从用户空间复制信息时出现问题。
EINTR
暂停已被传递给线程的信号中断(请参见signal(7))。剩余的睡眠时间已写入* rem,以便线程可以轻松地再次调用nanosleep()并继续进行暂停。
EINVAL
tv_nsec字段中的值不在0到999999999的范围内,或者tv_sec为负。

遵循规范

POSIX.1-2001,POSIX.1-2008。

备注

如果req中指定的间隔不是时钟基础粒度的精确倍数(请参见time(7)),则该间隔将舍入为下一个整数。此外,在睡眠完成之后,在CPU可以自由再次执行调用线程之前,仍可能会有延迟。

如果调用在被信号中断后重复重新启动,则nanosleep()休眠一定时间间隔的事实可能会出现问题,因为从中断到重新启动之间的时间间隔会导致休眠最终完成的时间发生漂移。通过使用带有绝对时间值的clock_nanosleep(2)可以避免此问题。

POSIX.1指定nanosleep()应该根据CLOCK_REALTIME时钟来测量时间。但是,Linux使用CLOCK_MONOTONIC时钟来测量时间。这可能无关紧要,因为clock_settime(2)的POSIX.1规范指出CLOCK_REALTIME的不连续更改不应影响nanosleep():

通过clock_settime(2)设置CLOCK_REALTIME时钟的值,对基于该时钟等待相对时间服务而被阻塞的线程(包括nanosleep()函数)无效。 ...因此,这些时间服务将在请求的相对间隔过去时终止,而与时钟的新值或旧值无关。

Old behavior

为了支持需要更精确的暂停的应用程序(例如,为了控制一些时间紧迫的硬件),nanosleep()会通过忙于以微秒为单位的精度等待从实际线程中调度的线程进行调用时处理最多2毫秒的暂停时间策略,例如SCHED_FIFO或SCHED_RR。此特殊扩展已在内核2.5.39中删除,因此在Linux 2.6.0及更高版本的内核中不可用。

BUGS

如果捕获信号并使用nanosleep()的程序以很高的速率接收信号,则在内核的睡眠间隔计算中调度延迟和舍入错误,并且返回的剩余值意味着在连续重启时,剩余值可能会稳定增加。 nanosleep()调用。为避免此类问题,请使用带有TIMER_ABSTIME标志的clock_nanosleep(2)进入绝对期限。

在Linux 2.4中,如果nanosleep()被信号(例如SIGTSTP)停止,则在通过SIGCONT信号恢复线程之后,调用将失败,并显示错误EINTR。如果随后重新启动系统调用,则不将线程花费在停止状态下的时间计入睡眠间隔。在Linux 2.6.0和更高版本的内核中已解决此问题。

另外参见

clock_nanosleep(2),restart_syscall(2),sched_setscheduler(2),timer_create(2),sleep(3),usleep(3),time(7)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/