fork与Vfork比较

1、典型的存储器安排

 

223103_7Ngu_1263856.png

2、fork函数:fork后,子进程获得父进程的数据空间、堆、栈、其缓冲区的副本但由于在fork之后经常跟随着exec,所以现实的很多实现并不执行父进程的数据段、栈和堆的完全复制

代码说明:

 #include "apue.h"
//如果标准输出连到 终端设备时,则它是行缓冲
//如果标准输出重定向到一个文件时,则它是全缓冲,因此before fork会输出两次到
int  ff=66;
char buf[]="a write to stdout\n";
int main(int argc,char ** argv){  
 int  var;
 pid_t  pid;
 var  =88; 
 if(write(STDOUT_FILENO,buf,sizeof(buf)-1)!=sizeof(buf)-1)//输出到标准输出
         err_sys("write error"); 
 printf("before fork\n");//该字符串存放在其缓冲区中(若是行缓冲,遇\n换行符就冲洗该缓冲区)

  if((pid=fork())<0){
         err_sys("fork error!!!"); 
 }
 else if(pid==0){ 
  ff++;
  var++;
 }
 else { 
  sleep(2);
 } 
 printf("pid=%d,glob=%d,var=%d\n",getpid(),ff,var);
 exit(0);
}


3、Vfork函数:vfork用于创建一个新进程,而该新进程的目的是exec一个新程序,因此它并不将父进程的地址空间完全复制到子进程中,相反,而是在子进程调用exec或exit之前,它在父进程的空间中运行(即与父进程共用同一数据段)

代码说明:

#include"apue.h"
int gg  =6;//全局变量
int main(int argc,char **argv){
 int  var;//局部变量
 var  =88;
 pid_t  pid;
 printf("before vfork\n");
 if((pid=vfork())<0){//vfork函数并不将父进程的地址空间完全复制到子进程中,而是子进程在调用exec或exit之前,和父进程共用空间
  err_sys("vfork error");
 } else if(pid==0){
  gg++;
  var++;
  //_exit(0);//不冲洗其缓冲区,直接进入内核
  exit(0);//冲洗父其缓冲区后,然后进入内核
 }
 printf("pid=%d, gg=%d ,var=%d\n",getpid(),gg,var);
 exit(0);
}

输出:

a write to stdout

before fork

pid=2472,glob=67,var=89

before fork//注意该字符串一共输出了两次

pid=2471,glob=66,var=88


转载于:https://my.oschina.net/lcxidian/blog/224880

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值