fork函數的詳細解釋

頭文件

#include<unistd.h>/*#包含<unistd.h>*/
#include<sys/types.h>/*#包含<sys/types.h>*/

函數原型

pid_t forkvoid);
(pid_t 是一個宏定義,其實質是int 被定義在#include<sys/types.h>中)
返回值: 若成功調用一次則返回兩個值,子進程返回0,父進程返回子進程ID;否則,出錯返回-1

函數說明

一個現有進程可以調用fork函數創建一個新進程。由fork創建的新進程被稱爲子進程(child process)。fork函數被調用一次但返回兩次。兩次返回的唯一區別是子進程中返回0值而父進程中返回子進程ID。
子進程是父進程的副本,它將獲得父進程數據空間、堆、棧等資源的副本。注意,子進程持有的是上述存儲空間的“副本”,這意味着父子進程間不共享這些存儲空間。
UNIX將複製父進程地址空間內容給子進程,因此,子進程有了獨立的地址空間。在不同的UNIX (Like)系統下,我們無法確定fork之後是子進程先運行還是父進程先運行,這依賴於系統的實現。所以在移植代碼的時候我們不應該對此作出任何的假設。
爲什麼fork會返回兩次?
由於在複製時複製了父進程堆棧段,所以兩個進程都停留在fork函數中,等待返回。因此fork函數會返回兩次,一次是在父進程中返回,另一次是在子進程中返回,這兩次的返回值是不一樣的。
  1. fork調用的一個奇妙之處就是它僅僅被調用一次,卻能夠返回兩次,它可能有三種不同的返回值:在父進程中,fork返回新創建子進程的進程ID;
  2. 在子進程中,fork返回0;
  3. 如果出現錯誤,fork返回一個負值。
在fork函數執行完畢後,如果創建新進程成功,則出現兩個進程,一個是子進程,一個是父進程。在子進程中,fork函數返回0,在父進程中,fork返回新創建子進程的進程ID。我們可以通過fork返回的值來判斷當前進程是子進程還是父進程。
引用一位網友的話來解釋fork函數返回的值爲什麼在父子進程中不同。“其實就相當於鏈表,進程形成了鏈表,父進程的fork函數返回的值指向子進程的進程id, 因爲子進程沒有子進程,所以其fork函數返回的值爲0.
調用fork之後,數據、堆棧有兩份,代碼仍然爲一份但是這個代碼段成爲兩個進程的共享代碼段都從fork函數中返回,箭頭表示各自的執行處。當父子進程有一個想要修改數據或者堆棧時,兩個進程真正分裂。


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