背景
之前的 blog
63、【OS】【Nuttx】任务休眠与唤醒:sleep
分析了任务休眠中的 sleep 函数,下面继续来分析下 sleep 函数中的核心功能 clock_nanosleep
clock_nanosleep
usleep
上篇 blog 分析了 sleep 函数,其核心功能封装到了 clock_nanosleep;不仅是 sleep,微秒级别的 usleep,其核心功能也是封装到了 clock_nanosleep
与 sleep 函数不同的是,usleep 不用传递 rmtp,即不用返回剩余未休眠时间,错误时返回 -1,包括被信号中断时的提前返回
描述
相对时间模式
clock_nanosleep 是 Nuttx 操作系统中实现纳秒级延时的函数,下面来看下它的描述
当 TIMER_ABSTIME 标志未置位时,函数将按照相对时间模式运行,此时,clock_nanosleep 将暂停执行当前线程,直到如下情况发生:
- 请求休眠的时间间隔已过,由 rqtp 参数指定的时间段已经过去,这里的 rqtp 是一个指向 struct timespec 结构体的指针,该结构体包含了秒数 (tv_sec) 和纳秒数 (tv_nsec)
- 接收到信号:如果在休眠期间有信号传递给调用线程,并且该信号的动作是调用信号处理函数,则 clock_nanosleep 会提前返回
- 进程终止:如果进程被终止(比如发送致命信号),clock_nanosleep 也会提前返回
休眠时间由 clock_id 参数指定的时钟来测量,clock_id 可以是操作系统定义的时钟之一,比如 CLOCK_REALTIME(系统实时时钟)或 CLOCK_MONOTONIC(单调递增时钟),用户可以在不同的时钟基准上进行休眠操作
绝对时间模式
当 TIMER_ABSTIME 标志被置位时,clock_nanosleep 将使用绝对时间来决定线程何时恢复执行
- 和相对时间模式类似,这里的区别主要在于当指定的时钟达到绝对时间,而不是时间间隔时,线程恢复执行
- 如果在调用的时刻,rqtp 指定的时间值小于或等于指定时钟的当前时间值,则 clock_nanosleep 会直接返回,不会挂起调用进程进入休眠
实际休眠时间
clock_nanosleep 在执行休眠操作时,实际的暂停时间可能比请求的时间长,主要考虑如下原因
- 操作系统有一个最小的睡眠单位,所有请求的时间都会被调整到这个单位的整数倍
- 操作系统需要调度其他任务,也可能导致实际的休眠时间延长。比如操作系统可能会优先处理更高优先级的任务,从而延迟当前线程的恢复
- 在相对时间模式下,除了被信号中断的情况,实际的休眠时间不会少于由 rqtp 参数指定的时间间隔
- 在绝对时间模式下,实际的休眠将至少持续到指定时钟的时间值达到 rqtp 中指定的绝对时间点,同样排除被信号中断的情况
函数定义
clock_nanosleep 的函数定义也没有太多有用的信息,主要实现逻辑被包装到 nxsig_clockwait 函数里了
下篇 blog 分析 nxsig_clockwait