您的位置:首页 > 其它

fork与vfork的区别

2016-02-24 17:10 253 查看
参考文章:http://blog.csdn.net/jianchi88/article/details/6985326

1.  fork  ():子进程拷贝父进程的数据段,代码段

    vfork ( ):子进程与父进程共享数据段


2.  fork ()父子进程的执行次序不确定

    vfork 保证子进程先运行,在调用exec 或exit 之前与父进程数据是共享的,在它调用exec

     或exit 之后父进程才可能被调度运行。 


3.  vfork ()保证子进程先运行,在她调用exec 或exit 之后父进程才可能被调度运行。如果在

   调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。 


案例

#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>

int main()
{
pid_t pid;
int cnt = 0;
pid = vfork();
if(pid<0)
printf("error in fork!\n");
else if(pid == 0)
{
cnt++;
printf("cnt=%d\n",cnt);
printf("I am the child process,ID is %d\n",getpid());
}
else
{
cnt++;
printf("cnt=%d\n",cnt);
printf("I am the parent process,ID is %d\n",getpid());
}
return 0;
} 执行结果:
cnt=1
I am the child process,ID is 4711
cnt=1
I am the parent process,ID is 4710
段错误
本来vfock()是共享数据段的,结果应该是2,为什么不是预想的2 呢?先看一个知识点:

vfork 和fork 之间的另一个区别是:vfork 保证子进程先运行,在她调用exec 或exit 之

后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动

作,则会导致死锁。
vfork ()创建子进程并没有调用exec 或exit,

所以最终将导致死锁。 

应该改成如下:

#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>

int main()
{
pid_t pid;
int cnt = 0;
pid = vfork();
if(pid<0)
printf("error in fork!\n");
else if(pid == 0)
{
cnt++;
printf("cnt=%d\n",cnt);
printf("I am the child process,ID is %d\n",getpid());
_exit(0);
}
else
{
cnt++;
printf("cnt=%d\n",cnt);
printf("I am the parent process,ID is %d\n",getpid());
}
return 0;

}

结果:
cnt=1
I am the child process,ID is 4711
cnt=2
I am the parent process,ID is 4710

网上抄的一段,可以再理解理解:

为什么会有vfork,因为以前的fork 很傻, 它创建一个子进程时,将会创建一个新的地址

空间,并且拷贝父进程的资源,而往往在子进程中会执行exec 调用,这样,前面的拷贝工

作就是白费力气了,这种情况下,聪明的人就想出了vfork,它产生的子进程刚开始暂时与

父进程共享地址空间(其实就是线程的概念了),因为这时候子进程在父进程的地址空间中

运行,所以子进程不能进行写操作,并且在儿子 霸占”着老子的房子时候,要委屈老子一

下了,让他在外面歇着(阻塞),一旦儿子执行了exec 或者exit 后,相 于儿子买了自己的

房子了,这时候就相 于分家了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: