进程创建(以及fork和vfork的区别)

进程创建

fork函数
#include<unistd.h>
pid_t fork(void)

返回值:自进程返回0,父进程返回子进程ID,出错返回-1
  • 进程调用fork函数时,当控制转移到内核中fork代码后,内核做的事情有:

    1. 分配新的数据块和数据结构给子进程

    2. 将父进程的数据结构的部分内容拷贝到子进程中

    3. 将子进程添加到系统进程列表

    4. fork返回。开始调度器调度

  • fork之前,父进程独立执行,fork之后,父子进程两个执行流分别执行,谁先谁后不确定,完全由调度器决定的。

  • 通常情况下,父子代码共享,父子在不写入的情况下都是共享的。当有一方试图写入时,便以写实拷贝各自一份副本进行写入。

  • 错误码EAGAIN表示达到进程数上线,ENOMEM表示没有足够空间给一个新进程分配

  • 所有由父进程打开的文件描述符都被复制到子进程中,父子进程中相同编号的文件描述符在内核中指向同一个file结构体,也就是说file结构体的引用计数要增加

  • fork常用的场景:

    1. 父进程希望复制自己,父子进程同时执行不同代码段(比如:父进程等待客户端请求,生成子进程来处理请求)

    2. 一个进程要执行不同的程序(比如:子进程从fork返回后调用exec函数)

vfork函数
#include<unistd.h>
pid_t vfork(void)

返回值:自进程返回0,父进程返回子进程ID,出错返回-1
  • 产生一个子进程,但父子进程共享数据段(共享地址空间)

  • vfork保证子进程先运行,等到子进程调用exec或者exit之后父进程才开始执行

  • 如果在调用exec或exit之前,子进程依赖于父进程进一步动作,则会造成死锁

  • 改变子进程变量的值,也是的父进程中的值发生改变,如果想改变共享数据段中的变量值,应该先拷贝父进程

fork和vfork的区别
  • fork产生子进程不共享地址空间,vfork产生子进程共享地址空间

  • fork不阻塞,父子进程可以同时执行,vfork阻塞,父进程要等待子进程执行完才能执行

  • fork后子进程和父进程的执行顺序不一定,vfork后子进程先执行,待到子进程退出后父进程才开始执行

猜你喜欢

转载自blog.csdn.net/wsq119/article/details/82108294