可以每個接觸到多程序程式設計的人在遇到fork()函數的時候都會由一些疑惑,它怎麼能傳回兩次?而且傳回值不同。對于以前的認知大家都知道一個函數隻能傳回依次啊。
呵呵,這就是fork的神奇所在,它為什麼這麼神奇?它是怎麼實作的?下面我根據自己得了解簡單的說一下,不過另外也歡迎大家的讨論。
首先要明白的就是fork函數的作用,它是用來建立一個子程序,和父程序一樣的子程序,就是父程序的一個副本。
子程序将會有自己的位址空間,并且會獲得父程序的資料段的副本以及堆棧的副本,所獲得的副本都是精确拷貝。所謂副本就是一模一樣的,包括變量,堆棧的結構。
另外有一點就是子程序和父程序共享代碼段。
fork函數如何傳回兩次值那?這就要說到子程序的建立了。
其實作過程大概是這樣:
首先在父程序中調用fork函數,在fork函數中開始的代碼中首先建立一個子程序空間,獲得一個程序ID,然後逐漸将資料段以及堆棧都拷貝過去,因為子程序的資料段以及堆棧都和父程序一樣,而且建立完成後就會和父程序共享代碼段,共同執行代碼,是以fork建立完子程序後面的代碼在子程序中也會執行,并且堆棧中也有fork函數等待傳回,這樣就可以在fork下面的代碼中進行實作傳回值了,在父程序中執行的時候就可以判斷目前程序的PID,如果等于剛剛建立程序的PID則傳回0,但是因為目前程序為父程序是以它的PID不會等于剛剛建立程序的PID,再往下執行如果不等于則傳回剛剛建立程序的PID,這樣父程序得到的fork傳回值就是建立子程序的PID。而在子程序中同樣會執行fork剩下的代碼,也會判斷目前程序的PID是否等于剛剛建立程序的PID,結果是等于的,因為是在子程序中,其本身就是剛剛建立的程序,是以既然等于則會傳回0,這樣子程序中得到的傳回值就是0,然後下面的代碼段在父程序和子程序中執行時就可以根據傳回值的不同而執行不同的代碼了。
其實在linux中fork傳回值的處理交給了一個do_fork的函數,這個函數根據傳入的值,然後會分别在子程序和父程序中執行,進而傳回兩次不同的值,具體過程和上面所說的實作思想差不多。
寫的比較亂,也都是我個人的了解,如果有不對的地方,希望大神們能夠指出來,非常感謝,同時也希望大家踴躍讨論一下。謝謝!