sleep、usleep、nanosleep函数


前言

提示:日常实习随想随记:
这是在学习i2c时,遇到其AT24cxx芯片,在写入一个8位数据字地址后,接收后,EEPROM将再次会响应0,此时寻址设备必须以停止条件终止写入序列。具体说明是下面详尽。
在这里插入图片描述

在这里插入图片描述

从而,在编程的时候需要注意的是:每次写入的时候是需要进行停歇一定时间,时间单位以微秒,纳秒进行计量。因此,便引入了sleep()、usleep()、nanosleep()


一、nanosleep()函数

//使用到的头文件
#include <time.h>

//函数的初始化  需要什么参数
int nanosleep(const struct timespec *req, struct timespec *rem);

// 结构题
struct timespec {
    time_t tv_sec;        /* seconds */
    long   tv_nsec;       /* nanoseconds */
};
  • 函数功能:
    • 暂停某个进程直到你规定的时间后恢复,参数req便就是需要进行暂停的时间,由上可知,reg是一个结构体,其中reg->tv_sec 是以秒为单位,reg->tv_nsec是以纳秒为单位。调用nanosleep是使进程进入TASK_INTERRUPTIBLE,这就意味着有可能会没有等到你规定的时间就因为其它信号而唤醒,此时函数返回-1,且剩余的时间会被记录在rem中。
  • 函数实现:
    • 将其状态设置成TASK_INTERRUPTIBLE,脱离就绪队列,然后进行一次进程调度再由内核在规定的时间后发送信号来唤醒这个进程。
  • 情景假设:
    • 我们假设时钟种中断是10纳秒一次,如果tv_sec = 0, tv_nsec = 2,那么时钟中断一定是在10纳秒后来唤醒这个进程的,这里我们看到任务的重新调度最少是在10纳秒之上,因此此函数的精确程度与时钟频率有关系,不过我们一般也不会延时在中断级别的时间范围内。

二、sleep()、usleep()、nanosleep()对比

  • sleep()和nanosleep()都是使进程睡眠一段时间后被唤醒,但是二者的实现完全不同。
  • Linux中并没有提供系统调用sleep(),sleep()是在库函数中实现的,它是通过调用alarm()来设定报警时间,调用sigsuspend()将进程挂起在信号SIGALARM上。
  • nanosleep()则是Linux中的系统调用,它是使用定时器来实现的,该调用使调用进程睡眠,并往定时器队列上加入一个timer_list型定时器,time_list结构里包括唤醒时间以及唤醒后执行的函数,通过nanosleep()加入的定时器的执行函数仅仅完成唤醒当前进程的功能。系统通过一定的机制定时检查这些队列(比如通过系统调用陷入核心后,从核心返回用户态前,要检查当前进程的时间片是否已经耗尽,如果是则调用schedule()函数重新调度,该函数中就会检查定时器队列,另外慢中断返回前也会做此检查),如果定时时间已超过,则执行定时器指定的函数唤醒调用进程。当然,由于系统时间片可能丢失,所以nanosleep()精度也不是很高。
  • 另外alarm()也是通过定时器实现的,但是其精度只精确到秒级,另外,它设置的定时器执行函数是在指定时间向当前进程发送SIGALRM信号

总结

引用https://blog.csdn.net/hbuxiaofei/article/details/46416605

提示:简单总结

  • 简单介绍了sleep,usleep,nanosleep三者之间的区别,可以更好的进行理解。
  • 25
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值