這里對(duì)Linux的進(jìn)程管理與調(diào)度做個(gè)簡(jiǎn)單的學(xué)習(xí)筆記總結(jié)。
一、進(jìn)程線程的概念
進(jìn)程:處于執(zhí)行期的程序以及相關(guān)資源的總稱。
線程:站在用戶空間來(lái)看,它是進(jìn)程的某一執(zhí)行路徑,站在內(nèi)核空間來(lái)看,它是一種特殊的進(jìn)程,與進(jìn)程一樣統(tǒng)一由task_struct描述。
二、進(jìn)程的描述
進(jìn)程主要由以下幾個(gè)部分組成:
- 代碼段:編譯后形成的一些指令
- 數(shù)據(jù)段:程序運(yùn)行時(shí)需要的數(shù)據(jù)
- 只讀數(shù)據(jù)段:常量
- 已初始化數(shù)據(jù)段:全局變量,靜態(tài)變量
- 未初始化數(shù)據(jù)段(bss):未初始化的全局變量和靜態(tài)變量
- 堆棧段:程序運(yùn)行時(shí)動(dòng)態(tài)分配的一些內(nèi)存
- PCB:進(jìn)程信息,狀態(tài)標(biāo)識(shí)等
task_struct結(jié)構(gòu)體:
系統(tǒng)用task_struct(進(jìn)程描述符)來(lái)描述進(jìn)程,該結(jié)構(gòu)定義在<Linux/sched.h>中,它包含一個(gè)具體進(jìn)程的所有信息。Linux通過(guò)slab分配器分配task_struct結(jié)構(gòu)。

pid :是進(jìn)程標(biāo)識(shí)值(身份證號(hào))。
它不是無(wú)限分配的
cat /proc/sys/kernel/pid_max
32位系統(tǒng) 最多只有32768個(gè)進(jìn)程號(hào)
因?yàn)檫M(jìn)程是系統(tǒng)最小資源分配單位,因此進(jìn)程內(nèi)也會(huì)有各種系統(tǒng)資源描述指針:
*mm :內(nèi)存資源
*fs :文件系統(tǒng)資源
*files :文件資源 (fd相關(guān))
*singal: 信號(hào)資源
等等
那么如何組織task_struct? 牽扯到數(shù)據(jù)結(jié)構(gòu)
鏈表:遍歷進(jìn)程
樹(shù):尋找父子關(guān)系
哈希:檢索

三、進(jìn)程的生命周期

對(duì)應(yīng)的進(jìn)程狀態(tài):
| 狀態(tài) | 縮寫 | 含義 |
|---|---|---|
| TASK_RUNNING | R | 正在運(yùn)行或可運(yùn)行 |
| TASK_INTERRUPTIBLE | S | 可中斷的休眠 |
| TASK_UNINTERRUPTIBLE | D | 不可中斷的休眠 |
| __TASK_STOPPED | T | 跟蹤狀態(tài), 當(dāng)進(jìn)程接收到SIGSTOP等signal信息 |
| __TASK_TRACED | t | 停止?fàn)顟B(tài),比如被debugger的ptrace() |
| EXIT_ZOMBIE | Z | 僵尸狀態(tài),即父進(jìn)程還沒(méi)有執(zhí)行waitpid() |
| EXIT_DEAD | X | 死亡狀態(tài) |
狀態(tài)切換:
- fork出來(lái)就處于就緒態(tài)
- 拿到cpu就處于運(yùn)行態(tài)
- 分時(shí)調(diào)度系統(tǒng),時(shí)間片用完搶占,切回就緒態(tài)
- 運(yùn)行時(shí)等資源的時(shí)候不能死等切換為睡眠態(tài)
- 等到了資源又切回就緒態(tài)
睡眠分為兩類:
深睡眠: 必須要等到我的資源來(lái)才會(huì)醒 ,不響應(yīng)信號(hào),kill -9 都不行。
淺睡眠: 信號(hào) 和 資源來(lái)了 都會(huì)醒。

操作系統(tǒng)都需要上面3個(gè)狀態(tài)。但是為什么Linux進(jìn)程生命周期會(huì)有5個(gè)狀態(tài)?
這里多了兩個(gè)狀態(tài):
1 僵尸態(tài)
僵尸態(tài)就是task_struct還沒(méi)有消失,但是進(jìn)程所依附的資源已經(jīng)釋放了,并且父進(jìn)程還沒(méi)有調(diào)wait4()的一個(gè)非常短的臨界階段。
進(jìn)程剛死的時(shí)候會(huì)變成僵尸,因?yàn)橘Y源已經(jīng)釋放,所以僵尸本身無(wú)內(nèi)存泄漏,它存在的目的是父進(jìn)程可以查到子進(jìn)程的死因,父進(jìn)程wait4()來(lái)收尸完成這個(gè)狀態(tài)的結(jié)束。
wait_task_zombie(){
...
}
子死父清理。
2 停止態(tài)
進(jìn)程在運(yùn)行時(shí)不去睡眠,人為的讓它死,再發(fā)個(gè)continue信號(hào),又進(jìn)入就緒態(tài)。
簡(jiǎn)單說(shuō)停止態(tài)就是停而不睡但也不死的狀態(tài)。睡眠態(tài)和停止態(tài)的區(qū)別是:睡眠態(tài)是自己睡的,停止態(tài)是被外部主動(dòng)暫停的。
操作:
ctrl + z 停止
bg/fg 恢復(fù)
限制cpu利用率:
cpulimit -l <百分比數(shù)> -p <pid>

參考:
宋寶華Linux的進(jìn)程、線程以及調(diào)度
《 Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)》
http://gityuan.com/2017/07/30/linux-process/