在上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重新執行,所以就死循環了。。。
請大家批評指正。。。
http://xxxxxx/Linuxjc/1136120.html TechArticle