本文分享了Linux vfork與fork簡單對比分析,分享給大家,具體如下:
fork相關問題:
一、fork基礎了解
fork作用為創建一個子進程,在使用了fork命令后,內核會分配新的內存塊和數據結構給子進程,并且將父進程的部分數據結構內容拷貝到子進程,最后再將子進程添加到系統進程列表中,添加完成后fork返回,開始調度。
頭文件:#include < unistd.h >
函數原型:pid_t fork( )
返回值:返回值大于0則當前進程為父進程,等于0代表為子進程,小于零代表創建子進程失敗。
通過一個例子來了解:
#include <stdio.h> #include <unistd.h> int main() { int tmp = 5; pid_t res = fork(); if(res < 0){ //fork失敗 perror("fork"); }else if(res == 0){ //該進程為子進程 printf("im child[%d],fasther is %d,tmp is %d./n",getpid(),getppid(),tmp++); }else{ //該進程為父進程 printf("im father[%d],tmp is %d./n",getpid(),tmp++); } p
運行結果:
im father[3128],tmp is 5.
tmp = 6 im child[3129],fasther is 1,tmp is 5. tmp = 6相關問題小結:
通過結果很明顯的能看出本次調用中,先執行父進程,對應pid為3128,在父進程中tmp++,所以輸出為6;關鍵問題在于子進程,有兩個關鍵點。
①為什么結果中子進程父親pid為1:通過輸出我們能看出父進程先執行完成后才執行的子進程,也就是說當子進程執行時父進程已結束,此時該子進程相當于一個孤兒進程,被pid為1也就是Init進程所管理,所以子進程的ppid為1;
②為什么子進程最后輸出tmp值還為6: fork進程采用的是寫時拷貝,父子進程一開始共享一片內存區域,但是只有有一方要對數據進行修改,則再開辟一塊空間,防止相互修改影響。所以在上述代碼中,雖說是一個tmp,其實內存中各自保留了一份值。
二、關于fork過程中寫時拷貝:
這下就不難看出,父子進程數據段和代碼段開始時是共享一塊對應的內存,當一方嘗試寫入時,便產生了寫時拷貝。需要注意的是:fork之前,父進程獨立執行,fork之后,父子兩個執行流分別執行,至于誰先執行,由調度器決定??赏ㄟ^下面例子很明顯的看出是從fork之后才分別執行。
#include <stdio.h> #include <unistd.h> int main() { int tmp = 5; printf("There is fork before/n"); pid_t res = fork(); if(res < 0){ //fork失敗 perror("fork"); }else if(res == 0){ //該進程為子進程 printf("im child[%d],tmp is %d./n",getpid(),tmp++); }else{ //該進程為父進程 printf("im father[%d],tmp is %d./n",getpid(),tmp++); } printf("tmp = %d/n",tmp); return 0; }
輸出結果:
There is fork before
im father[3625],tmp is 5.
tmp = 6
im child[3626],tmp is 5.
tmp = 6
三、fork調用失敗的原因:
新聞熱點
疑難解答