你的位置:首页 > 操作系统

[操作系统]return和exit函数的区别


在上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重新执行,所以就死循环了。。。

请大家批评指正。。。