關於fork的簡略版源碼剖析

首先聲明一下所剖析的源碼版本是Linux2.6.11.12
  • fork()函數和vfork()等都調用的是do_fork()函數,咱們所用的fork工做都是由do_fork()來進行的。

do_fork()函數:

  1. 進入後首先去經過查找pidmap_array位圖,尋找一個子進程所須要的新的pid
    alloc_pidmap();
  2. copy_process複製進程描述符.若是全部必須的資源都是可用的,該函數返回剛建立的task_struct描述符的地址。經過對copy_process()函數調用去複製拷貝父進程的資源,這裏採用的是寫時拷貝技術,若是一個頁面中的數據未改動,則父子進程公用一個資源頁,一旦有一點改動,哪怕是一個字節改動,都會將這個頁面從頭至尾都拷貝一份給子進程。這一步也是建立進程的關鍵。
    copy_process();

    而後調用dup_task_struct爲子進程得到進程描述符
    dup_task_struct();編程

    隨後進行一系列的安全檢查
    檢查系統中的進程數量(nr_threads)是否超過max_threads,max_threads的缺省值是由系統內存容量決定的。總的原則是:全部的thread_info描述符和內核棧所佔用的空間,不能超過物理內存的1/8。不過,系統管理能夠經過寫/proc/sys/kernel/thread-max文件來改變這個值。
    對子進程的描述符進行一系列初始化,分配pid安全

  3. 若是是vfork,那麼對父進程進行保護而後掛起父進程,讓子進程繼續執行;
    若是不是則調整父子進程的調度參數,若是父子進程運行在同一個CPU上,而且不能共享同一組頁表(CLONE_VM標誌被清0)。那麼,就把子進程插入父進程運行隊列。而且子進程插在父進程以前.這樣作的目的是:若是子進程在建立以後執行新程序,就能夠避免寫時複製機制執行沒必要要時頁面複製。不然,若是運行在不一樣的CPU上,或者父子進程共享同一組頁表.就把子進程插入父進程運行隊列的隊尾。

fork出來的子進程,基本上除了進程號以外父進程的全部東西都有一份拷貝,基本就意味着不是所有,下面咱們要說的是子進程從父進程那裏繼承了什麼東西,什麼東西沒有繼承。還有一點須要注意,子進程獲得的只是父進程的拷貝,而不是父進程資源的自己。session

由子進程自父進程繼承到:異步

  1. 進程的資格(真實(real)/有效(effective)/已保存(saved)用戶號(UIDs)和組號(GIDs))
  2. 環境(environment)
  3. 堆棧
  4. 內存
  5. 打開文件的描述符(注意對應的文件的位置由父子進程共享,這會引發含糊狀況)
  6. 執行時關閉(close-on-exec) 標誌 (譯者注:close-on-exec標誌可經過fnctl()對文件描述符設置,POSIX.1要求全部目錄流都必須在exec函數調用時關閉。更詳細說明,參見《UNIX環境高級編程》 W. R. Stevens, 1993, 尤晉元等譯(如下簡稱《高級編程》), 3.13節和8.9節)
  7. 信號(signal)控制設定
  8. nice值 (譯者注:nice值由nice函數設定,該值表示進程的優先級,數值越小,優先級越高)
    進程調度類別(scheduler class)(譯者注:進程調度類別指進程在系統中被調度時所屬的類別,不一樣類別有不一樣優先級,根據進程調度類別和nice值,進程調度程序可計算出每一個進程的全局優先級(Global process prority),優先級高的進程優先執行)
  9. 進程組號
  10. 對話期ID(Session ID) (譯者注:譯文取自《高級編程》,指:進程所屬的對話期(session)ID, 一個對話期包括一個或多個進程組, 更詳細說明參見《高級編程》9.5節)
  11. 當前工做目錄
  12. 根目錄 (譯者注:根目錄不必定是「/」,它可由chroot函數改變)
  13. 文件方式建立屏蔽字(file mode creation mask (umask))(譯者注:譯文取自《高級編程》,指:建立新文件的缺省屏蔽字)
  14. 資源限制
  15. 控制終端

子進程所獨有:函數

進程號.net

  1. 不一樣的父進程號(譯者注:即子進程的父進程號與父進程的父進程號不一樣, 父進程號可由getppid函數獲得)
  2. 本身的文件描述符和目錄流的拷貝(譯者注:目錄流由opendir函數建立,因其爲順序讀取,顧稱「目錄流」)
  3. 子進程不繼承父進程的進程,正文(text), 數據和其它鎖定內存(memory locks)(譯者注:鎖定內存指被鎖定的虛擬內存頁,鎖定後,
  4. 不容許內核將其在必要時換出(page out),詳細說明參見《The GNU C Library Reference Manual》 2.2版, 1999, 3.4.2節)
  5. 在tms結構中的系統時間(譯者注:tms結構可由times函數得到,它保存四個數據用於記錄進程使用中央處理器 (CPU:Central Processing Unit)的時間,包括:用戶時間,系統時間, 用戶各子進程合計時間,系統各子進程合計時間)
  6. 資源使用(resource utilizations)設定爲0
  7. 阻塞信號集初始化爲空集(譯者注:原文此處不明確,譯文根據fork函數手冊頁稍作修改)
  8. 不繼承由timer_create函數建立的計時器
  9. 不繼承異步輸入和輸出

參考:
http://blog.csdn.net/theone10...blog

相關文章
相關標籤/搜索