fork和vfork()函数都可以创建一个新的进程。主要的两个区别如下:
1.vfork()函数在创建子进程时,不会复制父进程的所有资源,相反,子进程共享父进程的内存,
直至其成功执行了exec()或者调用_exit()退出;
2.vfork()函数创建的子进程最后必须调用_exit()函数才能正确退出子进程,不能使用exit()函数。
为了更便于理解fork()和vfork()两个函数创建的子进程的区别,可以使用如下两个测试程序,来分别运行看一下:
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int idata = 111;
int main()
{
int istack = 222;
pid_t ChildPid;
switch (ChildPid = fork())//使用fork创建进程
{
case -1:
printf("fork create error!\n");
exit(1);
case 0:
idata *= 3;
istack *= 3;
printf("Child process, PID=%d,idata=%d,istack=%d\n",getpid (),idata,istack);
default:
sleep(3);
printf("Parent process, PID=%d,idata=%d,istack=%d\n",getpid(),idata,istack);
}
return 0;
}
运行结果 :
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int idata = 111;
int main()
{
int istack = 222;
pid_t ChildPid;
switch (ChildPid = vfork())//使用vfork创建进程
{
case -1:
printf("fork create error!\n");
exit(1);
case 0:
idata *= 3;
istack *= 3;
printf("Child process, PID=%d,idata=%d,istack=%d\n",getpid(),idata,istack);
_exit(0);创建的子进程必须调用_exit()函数才能正确退出
default:
sleep(3);
printf("Parent process, PID=%d,idata %d,istack=%d\n",getpid(),idata,istack);
}
return 0;
}
运行结果 :
如上所示的两组程序逻辑相同,只是分别调用了fork和vfork创建子进程。通过结果,可以看出,在第一个程序(fork)的结果中,在子进程中修改了idata和istack的值,等到再进入父进程时,值没有发生改变;在第二个程序(vfork)的结果中,在子进程中修改了idata和istack的值,等到再进入父进程时,值发生了改变。
通过这个比较,可以总结如下:
1.fork()创建的子进程拥有了自己的栈和数据段拷贝,而且,在子进程中对父进程变量的修改,不会影响父进程;
2.vfork()创建的子进程共享父进程的内存,所以在子进程中对父进程变量的修改,会影响父进程。
原文来自 --- https://blog.csdn.net/casky237/article/details/48882931