fork剖析資料

fork的流程

 分析一下do_fork()的源碼的主要步驟

1.首次查找_pidmap位圖,爲新子進程分配新的pid
圖片描述函數

2.複製進程描述符,返回的是新的進程描述符的地址(struct task_struct *p)
圖片描述spa

3.初始化完成量,vfrok主要用excv,父進程的虛擬地址空間對其沒有用處,因此實現方式爲在子進程退出或者替換後父進程纔開始執行
圖片描述線程

4.若是設置了vfork,則調用wait(父進程)3d

5.free_pidmap(pid):blog

6.返回子進程pid。繼承


對於第二步,是do_fork的關鍵

1.檢查flag位的合法性進程

2.爲子進程獲取進程描述符圖片

圖片描述

  開闢內核棧+thread_info 通常大小爲8kget

  將current的值賦給子進程
  源碼

3.檢查線程數量,設置一些關鍵字,保存新的pid

4.用系統調用時cpu寄存器中的值初始化新線程,將exa置爲0(fork和clone在子進程的返回值)

圖片描述

5.完成一些字段的設置,將新進程加入到鏈表,將新進程pid加入到散列表
圖片描述

複製父進程每個vm_area_struct,也複製它的頁表,將私有的可寫的頁都標記爲只讀,爲寫時拷貝作準備。

圖片描述
1.判斷是否爲建立線程,若是是線程,直接使用mm = oldmm ,表示線程公用虛擬地址空間

2.對於非線程,爲其建立虛擬地址空間,建立新的局部描述符加入到tsk地址空間,以後調用dup_mmap;

後續須要解決的問題:

1.current是什麼

task_struct 包含了進程全部的信息,current是一個宏,由getCurrent()->task替換,此函數內部是一條彙編指令,在x86體系下經過在內核棧尾部插入thread_info結構,計算偏移量,來查找到當前正在運行的進程描述符。

2.用戶態fork()->內核態sys_fork()的過程是什麼

普通程序調用fork()-->庫函數fork()-->系統調用(fork功能號)-->由功能號在 sys_call_table[]中尋到sys_fork()函數地址-->調用sys_fork(),這就完成拉從用戶態到內核態的變化過程。

總結一下:

  看源碼前對fork()只停留在用上,看了以後明白了不少死記硬背的點,也有了本身的理解。主要幾個點,fork的返回值,進程和線程的區別,vfork現階段還暫時沒有用過先記住吧,還包括子進程繼承父進程的信息,還有寫時拷貝的先決條件等。

相關文章
相關標籤/搜索