vfork()会产生一个新的子进程.但是vfork创建的子进程与父进程共享数据段.
看如下代码
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
int globVar = 5;
int main(void)
{
pid_t pid;
int var = 1,i;
printf("fork is different with vfork \n");
// pid = fork();
pid = vfork();
switch(pid) {
case 0:
i = 3;
while(i-- > 0)
{
printf("Child process is running\n");
globVar++;
var++;
printf("child globVar= %d,var= %d\n",globVar,var);
sleep(1);
}
printf("Child's globVar = %d,var = %d\n",globVar,var);
return 0;
//exit(0);
//break;
case -1:
perror("Process creation failed\n");
exit(0);
default:
i = 5;
while(i-- > 0) {
printf("Parent process is running\n");
globVar++;
var++;
printf("parent globVar= %d,var= %d\n",globVar,var);
sleep(1);
}
printf("Parent's globVar = %d,var = %d\n",globVar,var);
exit(0);
}
}
编译运行,结果如下:
lyt@lyt-N55SL:~/git/7$ ./a.out
fork is different with vfork
Child process is running
child globVar= 6,var= 2
Child process is running
child globVar= 7,var= 3
Child process is running
child globVar= 8,var= 4
Child's globVar = 8,var = 4
Parent process is running
parent globVar= 9,var= 32765
Parent process is running
parent globVar= 10,var= 32766
Parent process is running
parent globVar= 11,var= 32767
Parent process is running
parent globVar= 12,var= 32768
Parent process is running
parent globVar= 13,var= 32769
Parent's globVar = 13,var = 32769
有此可见,当vfork后的子进程 return 0 后,全局变量的值还是子进程修改后的值,但局部变量的值从4变到了32769,
然后,上边的代码将return 0注释掉,改为exit(0),var的值会从4开始增加,这是为什么?
这里就涉及到return 0 和exit(0)的区别了:
exit是一个函数,有参数;而return 时函数执行完后的返回.exit把控制权交给系统,而return将控制权交给调用函数.
- C/C++中,函数内部的一切变量(函数内部局部变量,形参 )都是在其被调用时才被分配内存单元。子函数运行结束时,所有局部变量的内存单元会被系统释放。
- 如果 main 函数的最后没有写 return 语句的话,C99 规定编译器要自动在生成的目标文件中(如 exe 文件)加入return 0;
如此,当子进程return 0之后,return会释放局部变量,并弹栈,回到上级函数执行,因为子进程时和父进程共享内存的,故而父进程的栈崩溃,无法正确运行.而子进程调用exit() 没有修改函数栈,所以,父进程得以顺利执行。