參考自:http://blog.csdn.net/dog_in_yellow/archive/2008/01/13/2041079.aspx
之前一直迷惑,什麼叫一次調用,兩次返回。經過上網搜索,終於知其起因。現將本身的理解記錄於此。
準備知識:
內存中的進程包括三個部分:可執行文件(即程序),相關數據(包括變量,內存空間,緩衝區等),上下文環境(我的理解爲從哪兒來,到哪兒去)。咱們知道,電腦CPU資源有限,單核就只有一個,多核也不是無限多。而當前運行的程序個數老是多於CPU個數的(這個應該是能夠想得通的,沒有哪一個製造商或我的那麼闊氣而浪費CPU)。所以在操做系統的調度之下,一個程序通常不會從頭執行到尾而不間斷,系統會按照程序執行的順序、優先級別等來確實由哪一個程序佔用當前CPU。而被間斷的那些程序就須要保存間斷時刻的狀態(即進程的三個部分都要記錄下來),以便再次執行可以徹底恢復到間斷之前,若是間斷的時間足夠短,應該給人很流暢的感受,這也就是爲何,咱們可以一邊聽音樂,一邊看這篇文章的緣故。我猜,這也是爲何運行在內存中的程序會被稱爲進程的緣故。
這樣,咱們就能夠開始討論fork函數了。假設一個進程中有一句代碼p=fork()。
咱們稱當前調用p=fork()的進程爲父進程,父進程pid號能夠用getpid()獲取。fork()返回一個值給變量p,此時p正常狀況下應該是一個正整數,表示fork()新產生的子進程的pid號。
fork()產生的那個子進程和父進程徹底相同(至少在父進程調用fork()那一瞬間是相同的),並且也是徹底獨立的(即執行的前後順序徹底由操做系統調度,且父進程不必定比子進程先執行完)。fork()函數並不一樣於通常的函數,父進程並不會等fork函數產生的子進程徹底執行完再執行pid=fork()後面的代碼。或者,能夠理解爲fork()的做用就是產生一個子進程,至於子進程是否運行、如何運行與它不要緊。
現討論子進程的執行。咱們知道,既然fork()是複製父進程,那麼p=fork()語句以前的狀況應該是徹底一致。在父進程中p變量獲得的是子進程的pid號,可是在子進程中一樣有這樣一個p變量,它的值是否是也是子進程的pid號呢?這是關鍵所在! 事實上,子進程中的p變量獲得的值不是子進程的pid號,而是0。子進程的pid號徹底能夠用getpid()在子進程中獲得。這也是爲何稱fork()一次調用,兩次返回,即最後的結果就等價於:一個程序被調用兩次造成兩個進程,在p=fork()以前,兩個進程徹底同樣,到這一句時,一個進程中p變量值爲另外一個進程的pid號,而另外一個進程中p變量值爲0,在這以後,兩個進程分道揚鑣,再無任何瓜葛。(注意,兩個進程能夠由同一個程序引發。)函數