fork与Vfork比较

1、典型的存储器安排

 

fork与Vfork比较

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


你可能感兴趣的:(fork与Vfork比较)