可以參考《深入Linux內核架構》第二章閱讀筆記。
1. 進程 process
-
程序本身並不是進程,進程是處於執行期的程序以及相關的資源的總稱。如:可執行代碼段、打開的文件、掛起的信號、內核內部數據、處理器狀態、一個或多個具有內存映射的內存地址空間以及一個或多個執行線程、存放全局變量的數據段等等。
-
實際上,進程就是正在執行的程序代碼的實時結果。
-
進程的另一個名字是任務(task)
2. 現代操作系統提供的兩種虛擬機制
-
虛擬處理器:讓正在分享同一個處理器的多個進程都覺着自己在獨享處理器
-
虛擬內存:讓進程在分配和管理內存時覺得自己擁有整個系統的所有內存資源
3. 進程描述符 task_struct
內核將進程的列表存放在叫做任務隊列(task list)的雙向循環鏈表中,鏈表中的每一項的類型都是task_struct,稱爲進程描述符,其中記錄了一個具體進程的所有信息。系統中的所有進程都通過其task_struct的tasks域串在一起。
4. 進程退出執行後會被設置爲僵死狀態,處於僵死態的進程所佔有的內存就是內核棧、thread_info結構體和task_struct機構,直到當它的父進程調用wait()或者waitpid()時,該進程的task_struct以及其所獨享的資源纔會全部釋放。
5. thread_info
在每個任務的內核棧的尾端都有一個struct thread_info結構體,該結構體中的task存放的是指向該任務實際task_struct的指針。
注:上圖中應該將 struct thread_struct 寫成 struct thread_info。
如對於ARM64架構的處理器:
/*
* how to get the current stack pointer from C
*/
registerunsignedlong current_stack_pointer asm("sp");
/*
* how to get the thread information struct from C
*/
staticinlinestruct thread_info *current_thread_info(void) __attribute_const__;
staticinlinestruct thread_info *current_thread_info(void)
{
return(struct thread_info *)
(current_stack_pointer &~(THREAD_SIZE -1));
}
6. current
使用current宏可以獲得當前正在運行的進程的task_struct,定義如下:
#define get_current()(current_thread_info()->task)
#define current get_current()
在進程通過系統調用或者觸發某個異常陷入內盒空間時,current宏才有效。
7. PID
-
內核通過一個唯一的進程標識值(process identification value)或者PID來標識每個進程。
-
類型是pid_t,存放在task_struct的pid域
-
目前PID的最大值是32768,表示系統中允許同時存在的進程的最大數目,可以通過修改/proc/sys/kernel/pid_max改變這個值。
8. 進程的狀態
在task_struct的state域描述了進程的當前狀態。一共有五種:
注:TASK_RUNNING —— 進程是可執行的;它或者正在執行,或者在運行隊列中等待。
9. 可以通過宏set_task_state(task, state)或者set_current_state(state)改變進程的狀態。
10. init進程的PID是1,task_struct的parent域指向其父進程,children域爲該進程的子進程鏈表。
11. 線程
-
Linux內核並沒有線程這一概念,它把所有的線程都當做進程來實現,線程僅僅被視爲一個與其他進程共享某些資源的進程
-
創建線程:
-
clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,0)
說明:
參數標誌 | 含義 |
CLONE_FILES | 父子進程共享打開的文件 |
CLONE_FS | 父子進程共享文件系統信息 |
CLONE_SIGHAND | 父子進程共享信號處理函數及背阻斷的信號 |
CLONE_VM |
父子進程共享地址空間 |
12. 內核線程
-
獨立運行與內核空間的標準進程
-
跟普通進程的區別是內核線程沒有獨立的地址空間(其task_struct的mm域爲NULL),只在內核空間運行
-
跟普通進程一樣可以被調度和搶佔
-
內核線程的創建也會調用clone
完。