进程中fork vfork的用法

来源:互联网 发布:怎么下载mod软件 编辑:程序博客网 时间:2024/05/21 06:52

在创建进程时,会用到fork 或vfork 创建子进程

1)copy- on write(fork)

      fork之后exec之前,父子进程的虚拟空间不同,但其对应的物理空间是同一个

    两个进程用的是相同的物理空间(内存区),子进程的代码段、数据段、堆栈都是指向父进程的物理空间!  (从左往右的大箭头表示的创建子进程的复制动作)



  当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间!

   如果是在子进程中调用了exec,由于两者执行的代码不同,子进程的代码段也会分配单独的物理空间。

 fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序,当进程调用一种exec函数时,该进程完全由新程序代换,而新程序则从其main函数开始执行,因为调用exec并不创建新进程,所以前后的进程id 并未改变,exec只是用另一个新程序替换了当前进程的正文,数据,堆和栈段。

2 ) vfork

1  vfork 不会将父进程的地址空间完全复制到子进程中,也不会复制页表。在子进程调用ecec 或者exit的之前,子程序会在父程序的空间运行,父进程阻塞。挂起)
2  vfork保证子进程先运行(fork不能保证),在她调用exec或exit之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。(从左到右的箭头表示的是共享)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



#include <sys/types.h>  #include <unistd.h>  #include <stdio.h>#include <stdlib.h>int glob = 6;  int main(){  int var;  pid_t pid;  var = 88;  printf("before fork\n");  if((pid = fork()) < 0){      perror("fork");      return 1;  }else if(pid == 0)//   子进程{            glob++;            var++;            _exit(0);          }          else     //    父进程{          printf("pid=%d,glob=%d,var=%d\n", getpid(),glob,var);            exit(0);        }  }/* fork时,由于glob 和 val 没有发生变化 ,说明父子进程在数据发生改变时,会独立分配给子进程一块儿物理空间。vfork 两个数据发生了改变,表示子进程在父进程空间中运行。*/
结果:

before fork
father process pid=4681,glob=6,var=88
son process pid=4682,glob=7,var=89

#include <sys/types.h>  #include <unistd.h>  #include <stdio.h>#include <stdlib.h>int glob = 6;  int main(){  int var;  pid_t pid;  var = 88;  printf("before vfork\n");  if((pid = vfork()) < 0){      perror("vfork");      return 1;  }else if(pid == 0)//   子进程{            glob++;            var++;  printf("son process pid=%d,glob=%d,var=%d\n", getpid(),glob,var);           _exit(0);          }          else     //    父进程{          printf("father process pid=%d,glob=%d,var=%d\n", getpid(),glob,var);            exit(0);        }  }
结果:

before vfork
son process pid=4670,glob=7,var=89
father process pid=4669,glob=7,var=89








0 0