程序管理的任務
程序能建立新的程序 (真正做到一個應用多程序)
确定哪個程序能夠擁有CPU
接受中斷并将中斷導向相應的核心子系統
向使用者程序發送信号
管理時鐘硬體
當一個程序結束時,釋放其資源
動态裝載執行子產品
相關概念簡介
程序就是處于執行期的程式。包括代碼段,占用的資源(打開的檔案,挂起的信号,核心内部資料,處理器狀态,記憶體位址空間)
線程,執行線程,是在程序中活動的對象。擁有獨立的程式計數器,程序棧,寄存器組。
核心排程的對象是線程,不是程序。
Linux線程實作很特别,對線程和程序并不特别區分。??隻是在資源共享上有差別??
程序描述符 PCB 在linux核心中的資料結構是task_struct 約1.7KB
程序家族樹 : 所有的程序都是PID為1的init程序的後代,核心在系統啟動的最後階段啟動init程序。Init程序描述符是作為init_task靜态配置設定的。
程序的狀态:
task_struct的state域中:
- TASK_RUNNING: 程序是可執行的程序要麼在執行,要麼在運作隊列中等待執行
- TASK_INTERRUPTIBLE:可中斷。程序正在睡眠,等待某些條件的達成。條件達成,核心就會把程序狀态設定為運作。也可以接收到信号而提前被喚醒。
- TASK_UNINTERUPTIBLE:不可中斷。接收到信号也不會投入運作。其他和可中斷相同。
- __TASK_TRACED:被其他程序跟蹤
- __TASK_STOPPED:程序停止。程序沒有投入運作,也不能投入運作。在接受到SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU等信号時調試期間收到這種信号,都會進入這種狀态。
- TASK__ZOMBIE僵屍,呆傻狀态,已結束,但其父程序未接到通知,描述符未釋放
- TASK_SWAPPING程序頁面被兌換出記憶體
- task_struct的exit_state域中有EXIT_ZOMBIE
[ 狀态轉換圖 ]

程序的管理
建立
fork系統調用,複制現有程序,可以接着調用exec函數組建立新的位址空間,并把新程式載入。
fork提高效率的措施
-
配置設定程序描述符:
預配置設定描述符(SLAB機制),把動态配置設定的過程省略掉一部分(不需要頻繁調用記憶體管理相應功能),相當于一種進階緩存,提高效率。最後的操作主要是直接填寫結構。
-
COPY_ON_WRITE :
寫時copy LINUX的FORK()過程并未為新生成的程序馬上複制代碼,開始的程序僅僅讀共享父程序代碼。直到程序第一次要對程序空間有寫請求時,再複制代碼。 這樣做的好處:效率高(一般新程序要有自己的代碼,第一條就是EXEC())
退出
程式通過exit系統調用退出執行。
程序退出(釋放資源)的過程exit
- task_struct 标志成員設定為PF_EXITING
- 調用del_timer_sync()删除任一核心定時器。
- 根據傳回的結果确定,確定沒有定時器在排隊,也沒有定時器程式在運作。
- 如果BSD的程序記賬功能開啟,do_exit調account_update_integrals來輸出記賬資訊
- 調用exit_mm(),釋放程序占用的mm_struct,如果沒有别的程序使用,徹底釋放他們。
- 調用sem__exit(). 如果程序排隊等候IPC信号,則離開隊列
- 調用exit_files(),exit_fs(),遞減檔案描述符,檔案系統的引用計數。如果技術為0,釋放資源。
- task_struct 的 exit_code成員中的退出代碼替換為EXIT()提供的代碼
調用exit_notify()向父程序發信号,給子程序尋找養父,程序狀态設定為EXIT_ZOMBIE
- 調用shedule切換到其他程序
删除程序描述符:
父程序wait,方法傳回後根據傳回代碼執行相應動作或者忽視。動作完成後真正釋放描述符。
調用relase_task
1. release調用__exit_signal,該函數調用_unhashprocess(),後者從pidhash上删除該程序。
2. 如果這是線程組的最後一個程序,且領頭程序死掉,通知僵死的領頭程序的父程序
3. 調用put_task_struct釋放描述符,核心棧,threadinfo所占的頁,slab高速緩存。
程序描述符的存放,使用current宏或者專門寄存器
參考 《linux核心設計與實作》