fork()和vfork()各自的特性

fork()

我们知道现代的fork()是已经应用了COW-Copy On Write的,父进程在fork()后创建的子进程先对父进程的数据段,堆段,栈段中的各页采用写时复制,令这些段的页表项指向父进程相同的物理内存页,并将这些页标记为只读!之后内核会通过写保护发现所有父进程或是子进程对页面的修改企图,并为将要修改的页面创建拷贝; 内核会将新的页面拷贝分配给遭到内核发现修改的进程; 之后父子进程可以分别修改各自的页拷贝而不再相互影响!
例子:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<string.h>
#include<stdlib.h>
static int idata = 1;//全局数据段

int main(int argc, char* argv[]){
        int istack = 1;//栈段
        pid_t childPid;

        switch(childPid = fork()){
                case -1:
                        fprintf(stderr,"fork Failed!");
                        exit(EXIT_FAILURE);
                        break;
                case 0:
                        istack *=4;
                        idata *=4;
                        break;
                default:
                        sleep(5);
                        break;
        }

        printf("PID=%d (%s) idata=%d istack=%d\n", childPid, (childPid==0)?"child":"parent",idata,istack);
        exit(EXIT_SUCCESS);
}

这个例子会发现,子进程对于栈段,数据段的修改是不会影响到父进程的(父进程不可见!);

vfork()

因为早期的fork()是完全对父进程内存空间的复制,在fork()后立即执行exec()的情况下是非常浪费的!出于这个原因引入了vfork(),它无需为子进程复制虚拟内存页或是页表,而是子进程共享父亲进程的内存,直到成功执行了exec()或是调用_exit()退出!而且在子进程结束之前会阻塞父进程的执行!注意这里和fork()的区别,fork()也是创建时父子进程共享内存,但是是对内存进行只读保护; 而vfork()是在遇到exec()才结束共享,是专门针对立即exec()的场景的!因此会出现子进程的修改父进程可见的怪异现象!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值