背景
之前的 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