創建進程的函數


clone()、fork()、vfork()都是Linux的系統調用。

進程一般由代碼段、數據段和PCB進程控制塊組成。

 

fork 創造的子進程復制了父親進程的資源,包括內存的內容task_struct內容,新舊進程使用同一代碼段,復制數據段和堆棧段,這里的復制采用了注明的copy_on_write技術,即一旦子進程開始運行,則新舊進程的地址空間已經分開,兩者運行獨立。

優點是子進程的執行獨立於父進程,具有良好的並發性。

缺點是兩者的通信需要專門的通信機制,如pipe、fifo和system V等。

其實在復制過程中,子進程復制了父進程的task_struct,系統堆棧空間和頁面表,在子進程運行前,兩者指向同一頁面。而當子進程改變了父進程的變量時候,會通過copy_on_write的手 段為所涉及的頁面建立一個新的副本。因此fork效率並不低。

 

vfork函數創建的子進程完全運行在父進程的地址空間上,子進程對虛擬地址空間任何數據的修改都為父進程所見。這與fork是完全不同的,fork進程是獨立的空間。另外一點不同的是vfork創建的子進程后,父進程會被阻塞,直到子進程執行exec()和exit()。

當創建子進程的目的僅僅是為了調用exec()執行另一個程序時,子進程不會對父進程的地址空間又任何引用。因此,此時對地址空間的復制是多余的,通過vfork可以減少不必要的開銷。

 

系統調用fork()和vfork()是無參數的,而clone()則帶有參數。fork()是全部復制,vfork()是共享內存,而clone()是則可以將父進程資源有選擇地復制給子進程,而沒有復制的數據結構則通過指針的復制讓子進程共享,具體要復制哪些資源給子進程,由參數列表中的clone_flags來決定。另外,clone()返回的是子進程的pid。 

輕量級進程由clone()函數創建。clone函數功能強大,帶了眾多參數,因此由他創建的進程要比前面2種方法要復雜。clone可以讓你有選擇性的繼承父進程的資源,你可以選擇想vfork一樣和 父進程共享一個虛存空間,從而使創造的是線程,你也可以不和父進程共享,你甚至可以選擇創造出來的進程和父進程不再是父子關系,而是兄弟關系

int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);
這里fn是函數指針,我們知道進程的4要素,這個就是指向程序的指針,就是所謂的“劇本", child_stack明顯是為子進程分配系統堆棧空 間(在linux下系統堆棧空間是2頁面,就是8K的內存,其中在這塊內存中,低地址上放入了值,這個值就是進程控制塊task_struct的 值),flags就是標志用來描述你需要從父進程繼承那些資源, arg就是傳給子進程的參數)。
 
系統調用服務例程sys_clone, sys_fork, sys_vfork三者最終都是調用do_fork函數完成.

do_fork的參數與clone系統調用的參數類似, 不過多了一個regs(內核棧保存的用戶模式寄存器). 實際上其他的參數也都是用regs取的

  • clone:
    •     clone的API外衣, 把fn, arg壓入用戶棧中, 然后引發系統調用. 返回用戶模式后下一條指令就是fn.
    •     sysclone: parent_tidptr, child_tidptr都傳到了 do_fork的參數中
    •     sysclone: 檢查是否有新的棧, 如果沒有就用父進程的棧 (開始地址就是regs.esp)
  • fork, vfork:
    •     服務例程就是直接調用do_fork, 不過參數稍加修改
    •     clone_flags:
      •    sys_fork: SIGCHLD|0;
      •    sys_vfork: SIGCHLD| (clone_vfork | clone_vm)
    •     用戶棧: 都是父進程的棧.
    •     parent_tidptr, child_ctidptr都是NULL.
以上有內容引用來自http://www.51develop.net/forum.php?mod=viewthread&tid=8963
 
 copy_process()創建進程描述符以及子進程執行所需要的所有其他數據結構。它的參數與do_fork()參數相同,外加子進程的PID。
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM