这个函数功能是暂停某个进程直到你规定的时间后恢复,参数req就是你要暂停的时间,其中req->tv_sec是以秒为单位,而tv_nsec以纳秒为单位(10的-9次方秒)。由于调用nanosleep是使进程进入TASK_INTERRUPTIBLE,这就意味着有可能会没有等到你规定的时间就因为其它信号而唤醒,此时函数返回-1,且剩余的时间会被记录在rem中。
这个函数的实现是:将其状态设置成TASK_INTERRUPTIBLE,脱离就绪队列,然后进行一次进程调度再由内核在规定的时间后发送信号来唤醒这个进程。
我们假设时钟种中断是10纳秒一次,如果tv_sec = 0, tv_nsec = 2,那么时钟中断一定是在10纳秒后来唤醒这个进程的,这里我们看到任务的重新调度最少是在10纳秒之上,因此此函数的精确程度与时钟频率有关系,不过我们一般也不会延时在中断级别的时间范围内。
下面我们再来比较linux下nanosleep() 和usleep、sleep()的区别
sleep()
usleep()
nanosleep()
sleep()和nanosleep()都是使进程睡眠一段时间后被唤醒,但是二者的实现完全不同。
Linux中并没有提供系统调用sleep(),sleep()是在库函数中实现的,它是通过调用alarm()来设定报警时间,调用sigsuspend()将进程挂起在信号SIGALARM上。
nanosleep()则是Linux中的系统调用,它是使用定时器来实现的,该调用使调用进程睡眠,并往定时器队列上加入一个timer_list型定时器,time_list结构里包括唤醒时间以及唤醒后执行的函数,通过nanosleep()加入的定时器的执行函数仅仅完成唤醒当前进程的功能。系统通过一定的机制定时检查这些队列(比如通过系统调用陷入核心后,从核心返回用户态前,要检查当前进程的时间片是否已经耗尽,如果是则调用schedule()函数重新调度,该函数中就会检查定时器队列,另外慢中断返回前也会做此检查),如果定时时间已超过,则执行定时器指定的函数唤醒调用进程。当然,由于系统时间片可能丢失,所以nanosleep()精度也不是很高。
另外alarm()也是通过定时器实现的,但是其精度只精确到秒级,另外,它设置的定时器执行函数是在指定时间向当前进程发送SIGALRM信号。
sleep 时间单位是秒
usleep的时间单位是微秒
select的精度是微妙,精确
struct timeval delay;
delay.tv_sec = 0;
delay.tv_usec = 20 * 1000; // 20 ms
select(0, NULL, NULL, NULL, &delay);
usleep()有有很大的问题
在一些平台下不是线程安全,如HP-UX以及Linux
usleep()会影响信号
在很多平台,如HP-UX以及某些Linux下,当参数的值必须小于1 * 1000 * 1000也就是1秒,否则该函数会报错,并且立即返回。
大部分平台的帮助文档已经明确说了,该函数是已经被舍弃的函数。
还好,POSIX规范中有一个很好用的函数,nanosleep(),该函数没有usleep()的这些缺点,它的精度是纳秒级。在Solaris的多线程环境下编译器会自动把usleep()连接成nanosleep()。
Linux下短延时推荐使用select函数,因为准确。
void my_usleep(unsigned int us)
struct timespec req, rem;
int ret;
req.tv_sec = us/1000000;
req.tv_nsec = us%1000000*1000;
ret = nanosleep(&req, &rem);
while (ret)
req = rem;
ret = nanosleep(&req, &rem);
return 0;
nanosleep()则是Linux中的系统调用,它是使用定时器来实现的,该调用使调用进程睡眠,并往定时器队列上加入一个timer_list型定时器,time_list结构里包括唤醒时间以及唤醒后执行的函数,通过nanosleep()加入的定时器的执行函数仅仅完成唤醒当前进程的功能。Linux中并没有提供系统调用sleep(),sleep()是在库函数中实现的,它是通过调用alarm()来设定报警时间,调用sigsuspend()将进程挂起在信号SIGALARM上。select的精度是微妙,精确。
【Linux C/C++ 延时(延迟)函数比较】介绍Linux系统中常用的延时函数sleep、usleep、nanosleep、select和std::sleep_for()的区别和使用场景
nanosleep()函数会导致当前的线程将暂停执行,直到rqtp参数所指定的时间间隔。或者在指定时间间隔内有信号传递到当前线程,将引起当前线程调用信号捕获函数或终止该线程。
#include
#include
#include
#include
void* pthread_do(void *arg)
struct timespec ts, ts1;
int c
close(3) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=1, tv_nsec=0}, NULL) = 0
close(1) = 0
可以发现sleep主要调
sleep()低精度休眠,精度是秒 ,可以被信号中断,如果被信号中断返回剩余秒数。所以sleep,alarm,setitimer 最好不要结合使用
nanosleep()高精度休眠,精度是纳秒,也是可以被信号中断。
二、函数接口
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
//函数原型 int nanosleep(struct timespec *req, struct timespec *rem)
//参数列表:
// req:要求的睡眠时间
// rem:剩余的睡眠时间
//返回值:
// 0:成功;-1,失败,errno保存错误代码
//目的:纳秒级别的延迟
int nano_delay(long delay)
struct timespe
参考:https://blog.csdn.net/lengzijian/article/details/9092367
1.
sleep的精度是秒
2.u
sleep的精度是微妙,不精确
3.select的精度是微妙,精确
struct timeval delay;
delay.tv_sec = 0;
delay.tv_usec = 20 * 1000; // 20 ms
在Linux中,让一个应用程序进入睡眠或暂停状态通常是为了节省系统资源或等待某些事件的发生。这种行为可以通过调用特定的系统调用来实现,最常用的是`sleep()`函数和`wait()`函数。
1. `sleep()`: 这个函数使得当前线程(通常是进程)暂停执行指定的时间,单位可以是秒、毫秒或微秒。例如,`sleep(5)`会让程序休眠5秒。这个函数常用于程序需要暂时停止执行,直到预定的时间到达。
2. `sleep(n)`: 如果你想要更精确地控制休眠时间,可以使用`nanosleep()`函数,它接受一个结构体参数,包含休眠的时间量,可以是纳秒级别。
3. `wait()`或`waitpid()`: 如果一个应用程序需要等待子进程结束,可以使用这些函数。它们会让主线程等待,直到子进程退出或满足其他条件。这通常用于多线程或者父进程管理子进程的上下文。
在调用这些函数之前,确保你了解它们的返回值和可能的错误处理,因为它们可能因中断或信号而提前返回。