fork与vfork的区别(注:vfork子进程不能return)(转)

1.vfork保证子进程先运行,在它调用exec或exit之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。

2.fork要拷贝父进程的进程环境;而vfork则不需要完全拷贝父进程的进程环境,在子进程没有调用exec和exit之前,子进程与父进程共享进程环境,相当于线程的概念,此时父进程阻塞等待。

 

为什么会有vfork呢?

因为以前的fork当它创建一个子进程时,将会创建一个新的地址空间,并且拷贝父进程的资源,然后将会有两种行为:

1.执行从父进程那里拷贝过来的代码段

2.调用一个exec执行一个新的代码段

 

当进程调用exec函数时,一个新程序替换了当前进程的正文,数据,堆和栈段。这样,前面的拷贝工作就是白费力气了,这种情况下,聪明的人就想出了vfork。vfork并不复制父进程的进程环境,子进程在父进程的地址空间中运行,所以子进程不能进行写操作,并且在儿子“霸占”着老子的房子时候,要委屈老子一下了,让他在外面歇着(阻塞),一旦儿子执行了exec或者exit后,相当于儿子买了自己的房子了,这时候就相当于分家了。

 

因此,如果创建子进程是为了调用exec执行一个新的程序的时候,就应该使用vfork

 

fork:拷贝了一份父进程的数据,也就是说父子之间互不干涉

vfork:与父进程共享同一份数据

 

程序参考:

复制代码
#include
#include
#include
int main(void) {
int var;
var = 88;
pid_t pid;
if ((pid = fork()) < 0) {
printf( "vfork error");
exit( -1);
} else if (pid == 0) { /* 子进程 */
var++;
printf( "pid=%d,var=%d\n", getpid(), var);
return 0;
//exit(0);
}
printf( "pid=%d,var=%d\n", getpid(), var);
return 0;
复制代码

运行结果:

pid= 4684,var= 89
pid= 4683,var= 88

因为此处用的是fork,所以父子之间互不干涉。

子进程中的var加一后,变为89。

而父进程中的var依然为88。

 

如果改为vfork,结果为:

pid= 4785,var= 89
pid= 4784,var= 89

因为共享数据了。

 

如果直接粘贴上述代码,只将fork改为vfork,会出现段错误。

原因是,在fork中用return语句是允许的。

因为子进程是复制了一份数据。

然而,在vfork中用return语句,因为父子共享,则会导致栈的崩溃。

也就是父进程不能够继续执行下去了。

因此,在vfork中需要用exit()函数。

 

转自:https://www.huaweicloud.com/zhishi/arc-9555487.html

posted @   鸭子船长  阅读(171)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2018-08-02 android N : UnsatisfiedLinkError 只能访问设置为公用库的so库
2018-08-02 android openCL的so库目录(转)
2017-08-02 linux 终端分屏命令vsp(转)
点击右上角即可分享
微信分享提示