在現代操做系統中,進程提供兩種虛擬機制:linux
虛擬處理器 虛擬內存
幾個函數:緩存
fork():建立新進程 exec():建立新的地址空間並把新的程序載入其中 clone():fork實際由clone實現 exit():退出執行 wait4():父進程查詢子進程是否終結
wait()、waitpid():程序退出執行後變爲僵死狀態,調用這兩個消滅掉。函數
X86系統中,current把棧指針的後13個有效位屏蔽掉,用來計算出threadinfo的偏移(currentthread_info函數)學習
movl $-8192, %eax andl %esp,%eax
進程描述符中的state域是用來描述進程當前狀態的。共有五種狀態,標誌以下:操作系統
狀態轉換圖以下:線程
使用settaskstate(task,state)函數.設計
settaskstate(task,state); //將任務task的狀態設置爲state指針
setcurrentstate(state) 和下面等價調試
對於給定的進程,獲取鏈表中下一個進程:code
- list_entry(task->tasks.prev,struct - task_struct,tasks)
通常操做系統產生進程的機制:
1. 在新的地址空間建立進程 2. 讀入可執行文件 3. 執行
Unix的機制:
fork()和exec()。 fork(): 經過拷貝當前進程建立一個子進程。
子進程與父進程的區別僅在於PID,PPID和某些資源和統計量
exec(): 讀取可執行文件並將其載入地址空間開始運行。
-** Linux經過clone系統調用實現fork** - 建立進程的大概步驟以下:
fork()、vfork()、__clone()都根據各自須要的參數標誌調用clone()。 由clone()去調用do_fork()。 do_fork()調用copy_process()函數,而後讓進程開始運行。 返回do_fork()函數,若是copy_process()函數成功返回,新建立的子進程被喚醒並讓其投入運行。
通常內核會選擇子進程首先執行。
除了不拷貝父進程的頁表項以外,vfork()系統調用和fork()的功能相同。理想狀況下不要調用vfork()。
子進程做爲父進程的一個單獨的線程在它的地址空間裏運行 ,父進程被阻塞,直到子進程退出或執行exec()。子進程不能向地址空間寫入。
vfork()系統調用的實現是經過向clone()傳遞一個特殊標誌來進行的。
調用copyprocess()是,taskstruct的vfor_done成員被設置爲NULL。
與普通進程相似,只不過在調用clone()的時候須要傳遞一些參數標誌來指明共享的資源
與普通進程的區別只在於內核線程沒有獨立的地址空間。
- 它只能經過其餘內核線程建立;內核經過kthread內核進程衍生全部的內核線程 - 新建立的線程處於不可運行狀態,直到wake_up_process()明確地喚醒它
## 3.5 進程終結 ## - 進程終結時,內核必須釋放它所佔有的資源並告知父進程。
進程終結的緣由:通常是來自自身,發生在調用exit()系統調用時。
顯式的調用 隱式的從某個程序的主函數返回
大部分依賴於do_exit()來完成。其中有幾個重點:
…… 給子進程從新找養父(線程組中的其餘線程或者init進程) 調用schedule()切換到新的進程 ……
釋放task_struct結構發生在父進程得到已終結的子進程信息而且通知內核不關注後,須要的系統調用是wait4():
掛起調用它的進程,直到其中的一個子進程退出,此時函數返回該子進程的PID。
- do_exit()-- - >forget_original_parent()- - >find_new_parent()- - >ptrace_exit_finish() - (這一函數是爲被跟蹤的進程尋找父進程,由於被跟蹤的進程會以調試程序做爲臨時父親)
在本章中,我知道了操做系統的核心概念--進程,也跟着書本學習了進程的通常特性的重要性等等,頗有趣。
《linux內核設計與實現》原書第三版