http://blog.chinaunix.net/uid-16738490-id-2863829.html
传统的fork()在创建新的子进程的时候会复制所有父进程所拥有的资源。当然,这一特点有它不尽如人意的地方:使用fork()创建新的进程的目的往往不是为了创建一个和父进程完全一样的进程,很多时候是为了调用exec来执行另一个可执行程序。因此,复制所有父进程的资源是多余的操作。
当使用vfork()系统调用来创建子进程的时候,不会复制父进程的相关资源,父子进程将共享地址空间。子进程对虚拟内存空间的任何修改实际上是在修改父进程虚拟内存空间的内容。在使用vfork()创建子进程后,父进程会被阻塞,直到子进程调用了exec或者_exit()退出。子进程不能使用return返回或调用exit(),但是可以调用_exit()。
通过共享父进程的地址空间,vfork()避免了fork()带来的资源复制消耗。
举例说明两者区别:
程序p1.c和p2.c在子进程中修改了全局变量的取值,在父进程中显示同名变量的取值。
//p1.c
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int g_var=0;
int main(void)
{
pid_t pid;
int var=1;
//输出fork()调用前的变量取值
printf(“process id:%ld\n”,(long)getpid());
printf(“before execute the fork system call,g_var=%d var=%d\n”,g_var,var);
//在子进程中改变变量取值,并输出
if((pid=fork())<0)
{
perror(“Can’t create a new process”);
return 1;
}
else if(pid==0)
{
g_var++;
var++;
printf(“process id:%ld,g_var=%d var=%d\n”,(long)getpid(),g_var,var);
_exit();
}
//输出父进程中的取值情况
printf(“process id:%ld,g_var=%d var=%d\n”,(long)getpid(),g_var,var);
return 0;
}
用gcc编译并运行,结果
michenggang@michenggang-desktop:~$ gcc –o p1 p1.c
michenggang@michenggang-desktop:~$ ./p1
process id:24537
before execute the fork system call,g_var=0 var=1
process id:24538,g_var=1 var=2
process id:24537,g_var=0 var=1
可以看到在子进程中改变变量不会影响父进程中变量的取值。
修改上边的程序,将其中使用fork()的语句进行替换,使用vfork(),并将代码保存为p2.c。编译并运行,结果
michenggang@michenggang-desktop:~$ gcc –o p2 p2.c
michenggang@michenggang-desktop:~$ ./p2
process id:24574
before execute the fork system call,g_var=0 var=1
process id:24538,g_var=1 var=2
process id:24537,g_var=1 var=2
可以看到子进程修改变量会导致父进程中对应变量值的改变。
http://blog.csdn.net/lishiyong110/article/details/5385778