Linux fork()分析

Linux通過clone()系統調用實現fork()。這個系統調用通過一系列的參數標誌來指明父、子進程需要共享的資源。fork()、vfork()和__clone()庫函數都根據各自需要的參數標誌去條用clone(),然後由clone()去調用do_fork()。
do_fork()完成了創建中的大部分工作,他的定義在kernel/fork.c文件中。該函數調用copy_process()函數,然後讓進程開始運行。copy_process()函數完成的工作如下:
(1)調用dup_task_struct()爲新進程創建一個內核棧、thread_info結構和task_struct,這些值與當前進程的值相同。此時,子進程和父進程的描述符完全相同。
(2)檢查並確保新創建這個子進程後,當前用戶所擁有的進程數目沒有超過給它分配的資源的限制。
(3)子進程着手使自己與父進程區別開來。進程描述符內的許多成員都要被清0或設爲初始值。那些不是繼承而來的進程描述符成員,主要是統計信息。task_struct中的大多數數據都依然爲被修改。
(4)子進程的狀態被設置爲TASK_UNINTERRUPTIBLE,以保證他不會投入運行。
(5)調用copy_flags()以更新task_struct的flags成員。表明進程是否擁有超級用戶權限的PF_SUPERPRIV標誌被清0。表明進程還沒有調用exec()函數的PF_FORKNOEXEC標誌被設置。
(6)調用alloc_pid()爲新進程分配一個有效的PID。
(7)根據傳遞給clone()的參數標誌,copy_process()拷貝或共享打開的文件、文件系統信息、信號處理函數、進程地址空間和命名空間等。在一般情況下,這些資源會被給定進程的所有線程共享;否則,這些資源對每個進程都是不同的,因此被拷貝到這裏。
(8)最後,copy_process()做掃尾工作並返回一個指向子進程的指針。
再回到do_fork()函數,如果copy_process()函數成功返回,新創建的子進程被喚醒並讓其投入運行。內核有意選擇子進程首先執行。因爲一半子進程都會馬上調用exec()函數,這樣可以避免寫時拷貝的額外開銷,如果父進程首先執行的話,有可能會開始向地址空間寫入。
這裏寫圖片描述

如有錯誤請指正

發佈了56 篇原創文章 · 獲贊 118 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章