在上Linux課的時候,老師提到一句,調用vfork產生的子進程就是為了使用exec族函數來執行其他的代碼邏輯。 在子進程退出的時候有兩種方式,exit和exec族函數,不能使用return,為什麼不能用return呢,為什麼只有vfork會不讓用return呢? 於是我就寫了這樣的代碼 不出所料出 ...
在上Linux課的時候,老師提到一句,調用vfork產生的子進程就是為了使用exec族函數來執行其他的代碼邏輯。
在子進程退出的時候有兩種方式,exit和exec族函數,不能使用return,為什麼不能用return呢,為什麼只有vfork會不讓用return呢?
於是我就寫了這樣的代碼
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 5 6 int main() 7 { 8 pid_t pid; 9 pid=vfork(); 10 if(pid==0) 11 { 12 //child 13 printf("I am child pid:%d\n",getpid()); 14 ···· 15 return 0;16 } 17 else 18 { 19 //father 20 printf("I am father pid:%d\n",getpid()); 21 } 22 return 0; 23 }
不出所料出錯了
而且根據操作系統的版本不同,出錯結果可能不同,有的系統可能會死迴圈,一直交替輸出上面圖中的兩句話。
那麼,為什麼呢?return 和 exit 函數都可以讓一個進程結束,為什麼結果會有這麼大的差距呢?而且為什麼fork沒事,vfork就會有錯呢?
首先先找他們之間的不同點,fork和vfork最大的不同當然就是父子進程的地址空間問題了,vfork產生的子進程和父進程共用同一個地址空間,那麼也就是說,從地址空間的底部到頂部,全是通用的,一個改了,另外一個的數據也就被修改了。
然後我們再看return 和 exit ,簡單的來說都是退出用的,會刷新緩衝區之類的,然後退出,但是!從字面意思可以看出return有返回的意思,我之前的博客講述過函數棧幀的構造方式,當函數返回上一級調用它的函數的時候,棧幀中的指針會產生移動,“返回”的意義就在這裡!!!返回上一級調用它的函數,然後修改棧幀指針以返回,那麼再看之前說的vfork產生的子進程和父進程是共用地址空間的,那麼棧也包含在裡面咯~,子進程一旦使用return就會把棧(其中的函數棧幀,尤其是main)改寫!簡單的說就是子進程把main幹掉的時候順手就把父進程也拉上了,父進程表示什麼都不知道就死了。。。這時候系統會報段錯誤,但是有的操作系統會讓父進程回到main重新執行,所以就死迴圈了。。。
請大家批評指正。。。