1開場(chǎng)白
環(huán)境:
- 處理器架構(gòu):arm64
- 內(nèi)核源碼:linux-5.10.50
- ubuntu版本:20.04.1
- 代碼閱讀工具:vim ctags cscope
無論是任務(wù)處于用戶態(tài)還是內(nèi)核態(tài),經(jīng)常會(huì)因?yàn)榈却承┦录撸赡苁堑却齀O讀寫完成,也可能等待其他內(nèi)核路徑釋放一把鎖等)。本文來探討一下,任務(wù)處于睡眠中有哪些狀態(tài)?睡眠對(duì)于任務(wù)來說究竟意味著什么??jī)?nèi)核是如何管理睡眠的任務(wù)的?我們會(huì)結(jié)合內(nèi)核源代碼來分析任務(wù)的睡眠,力求全方位角度來剖析。注:由于篇幅問題,文章分為上下兩篇,且這里不區(qū)分
進(jìn)程和任務(wù),統(tǒng)一使用任務(wù)來表示進(jìn)程。主要講解以下內(nèi)容:
- 睡眠的三種狀態(tài)
- 睡眠的內(nèi)核原理
- 用戶態(tài)睡眠
- 內(nèi)核態(tài)睡眠
- 總結(jié)
2. 睡眠的三種狀態(tài)
任務(wù)睡眠有三種狀態(tài):
淺度睡眠?中度睡眠?深度睡眠2.1 淺度睡眠
進(jìn)程描述符的state使用
TASK_INTERRUPTIBLE表示這種狀態(tài)。為可中斷的睡眠狀態(tài),這里可中斷是可以被信號(hào)所打斷(喚醒)。這里給出被信號(hào)打斷/喚醒的代碼路徑:
kernel/signal.c
SYSCALL_DEFINE2(kill,?pid_t,?pid,?int,?sig)
->kill_something_info
????->__kill_pgrp_info
????????->group_send_sig_info
????????????->do_send_sig_info
????????????????->send_signal
????????????????????->__send_signal??
????????????????????????->complete_signal
????????????????????????????->signal_wake_up
?????????????????????????????????->?signal_wake_up_state(t,?resume???TASK_WAKEKILL?:?0)?
????????????????????????????????????->wake_up_state(t,?state?|?TASK_INTERRUPTIBLE)
????????????????????????????????????????->try_to_wake_up
可以看到在信號(hào)傳遞的時(shí)候,會(huì)通過signal_wake_up喚醒從處于可中斷睡眠狀態(tài)的任務(wù)。
2.2 中度睡眠
進(jìn)程描述符的state使用
TASK_KILLABLE表示這種狀態(tài)。可以被致命信號(hào)所打斷。這里給出被致命信號(hào)打斷/喚醒的代碼路徑:
include/linux/sched.h
#define?TASK_KILLABLE???????????????????(TASK_WAKEKILL?|?TASK_UNINTERRUPTIBLE)
kernel/signal.c
SYSCALL_DEFINE2(kill,?pid_t,?pid,?int,?sig)
->kill_something_info
????->__kill_pgrp_info
????????->group_send_sig_info
????????????->do_send_sig_info
????????????????->send_signal
????????????????????->__send_signal??
????????????????????????->complete_signal
?????????????????????????->
????????????????????????????????if?(sig_fatal(p,?sig)?