进程创建——fork,vfork

fork()函数:

在Linux中fork函数是一个非常重要的函数,它从已存在的进程中创建一个新的进程,而新进程位子进程,原进程位父进程

函数原型:

#include<unistd.h>
pid_t fork(viod);

返回值:成功子进程中返回0,父进程返回子进程的id,出错返回-1

调用fork函数:

进程调用fork,当控制转移到内核中的fork代码后,内核会做以下几件事 

  • 分配下的内存块和内核数据结构给子进程(将进程加载到内存)
  • 将父进程部分数据结构拷贝到子进程
  • 将子进程加入到调度队列
  • fork返回后,开始调度器调度(凭优先级调度)

当一个进程调用fork返回后,就有俩个二进制代码相同的进程。而且他们都运行到相同的地方。但每个进程可以干他们自己的事

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 
  5 int main()
  6 {
  7     pid_t pid;
  8     printf("Before:pid is %d\n",getpid());
  9     if((pid = fork())<0)
 10     {
 11         perror("fork");
 12         exit(1);
 13     }
 14     printf("After:pid is %d,fork return %d\n",getpid(),pid);
 15     sleep(1);
 16     return 0;
 17 }

运行结果如下: 

我们看到运行结果有三行,一行before,但是调用了fork之后输出两行after。为什么会这样呢?

 

由此可见,fork之前只有父进程独立执行,fork之后,父子进程俩个执行流分别执行。

注意!fork之后,父子进程谁先执行完全由调度器决定!!

写时拷贝: 

通常父子进程共享代码,父子进程在不写入时,数据也是共享的,当任意一方写入,便以写时拷贝的方式各自一份副本。如下图所示:

fork的常规用法:

  • 一个进程希望复制自己,使得父子进程同时执行不同的代码段。(如:父进程等待客户端请求,生成子进程来处理请求)
  • 一个进程要执行一个不同的程序,例如子进程从fork返回后,调用exec函数 

fork调用失败的原因:

  • 系统中有太多的进程
  • 实际用户的进程数超过了限制(Linux事一款多用户的操作系统,每个人创建的进程是有上限的)

vfork()函数:

vfork和fork一样,也是用来创建子进程的

函数原型:

#include<unistd.h>
#include<sys/types.h>
pid_t vfork(void);

返回值:父进程返回子进程的id,子进程返回0

fork和vfork的区别:

  • vfork共享地址空间,vfork创建一个子进程,父子进程的PCB指向同一块物理空间。而fork的子进程具有自己独立的地址空间
  • vfork保证子进程先运行,在它调用exec(或exit)之后,父进程才能被调度执行。而fork的父子进程执行顺序由调度器决定 

我们来看一段代码:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<sys/types.h>
  5 
  6 int glob = 100;
  7 
  8 int main()
  9 {
 10     pid_t pid = vfork();
 11     if((pid<0))
 12     {
 13         perror("fork");
 14         exit(1);
 15     }
 16     else if(pid==0)//child
 17     {
 18         glob = 200;
 19         printf("child glob %d\n",glob);
 20         exit(0);
 21     }
 22     else//father
 23     {
 24         printf("father glob %d\n",glob);
 25     }
 26     return 0;
 27 }
      

运行结果如下:

 

我们之修改了子进程中的glob,然而父进程中的值页改变了,由此可见子进程和父进程在同一块可见内运行,而且保证子进程先运行 

猜你喜欢

转载自blog.csdn.net/audience_fzn/article/details/81583962