关于fork的简略版源码剖析

首先声明一下所剖析的源码版本是Linux2.6.11.12
  • fork()函数和vfork()等都调用的是do_fork()函数,咱们所用的fork工做都是由do_fork()来进行的。

do_fork()函数:

  1. 进入后首先去经过查找pidmap_array位图,寻找一个子进程所须要的新的pid
    alloc_pidmap();
  2. copy_process复制进程描述符.若是全部必须的资源都是可用的,该函数返回刚建立的task_struct描述符的地址。经过对copy_process()函数调用去复制拷贝父进程的资源,这里采用的是写时拷贝技术,若是一个页面中的数据未改动,则父子进程公用一个资源页,一旦有一点改动,哪怕是一个字节改动,都会将这个页面从头至尾都拷贝一份给子进程。这一步也是建立进程的关键。
    copy_process();

    而后调用dup_task_struct为子进程得到进程描述符
    dup_task_struct();编程

    随后进行一系列的安全检查
    检查系统中的进程数量(nr_threads)是否超过max_threads,max_threads的缺省值是由系统内存容量决定的。总的原则是:全部的thread_info描述符和内核栈所占用的空间,不能超过物理内存的1/8。不过,系统管理能够经过写/proc/sys/kernel/thread-max文件来改变这个值。
    对子进程的描述符进行一系列初始化,分配pid安全

  3. 若是是vfork,那么对父进程进行保护而后挂起父进程,让子进程继续执行;
    若是不是则调整父子进程的调度参数,若是父子进程运行在同一个CPU上,而且不能共享同一组页表(CLONE_VM标志被清0)。那么,就把子进程插入父进程运行队列。而且子进程插在父进程以前.这样作的目的是:若是子进程在建立以后执行新程序,就能够避免写时复制机制执行没必要要时页面复制。不然,若是运行在不一样的CPU上,或者父子进程共享同一组页表.就把子进程插入父进程运行队列的队尾。

fork出来的子进程,基本上除了进程号以外父进程的全部东西都有一份拷贝,基本就意味着不是所有,下面咱们要说的是子进程从父进程那里继承了什么东西,什么东西没有继承。还有一点须要注意,子进程获得的只是父进程的拷贝,而不是父进程资源的自己。session

由子进程自父进程继承到:异步

  1. 进程的资格(真实(real)/有效(effective)/已保存(saved)用户号(UIDs)和组号(GIDs))
  2. 环境(environment)
  3. 堆栈
  4. 内存
  5. 打开文件的描述符(注意对应的文件的位置由父子进程共享,这会引发含糊状况)
  6. 执行时关闭(close-on-exec) 标志 (译者注:close-on-exec标志可经过fnctl()对文件描述符设置,POSIX.1要求全部目录流都必须在exec函数调用时关闭。更详细说明,参见《UNIX环境高级编程》 W. R. Stevens, 1993, 尤晋元等译(如下简称《高级编程》), 3.13节和8.9节)
  7. 信号(signal)控制设定
  8. nice值 (译者注:nice值由nice函数设定,该值表示进程的优先级,数值越小,优先级越高)
    进程调度类别(scheduler class)(译者注:进程调度类别指进程在系统中被调度时所属的类别,不一样类别有不一样优先级,根据进程调度类别和nice值,进程调度程序可计算出每一个进程的全局优先级(Global process prority),优先级高的进程优先执行)
  9. 进程组号
  10. 对话期ID(Session ID) (译者注:译文取自《高级编程》,指:进程所属的对话期(session)ID, 一个对话期包括一个或多个进程组, 更详细说明参见《高级编程》9.5节)
  11. 当前工做目录
  12. 根目录 (译者注:根目录不必定是“/”,它可由chroot函数改变)
  13. 文件方式建立屏蔽字(file mode creation mask (umask))(译者注:译文取自《高级编程》,指:建立新文件的缺省屏蔽字)
  14. 资源限制
  15. 控制终端

子进程所独有:函数

进程号.net

  1. 不一样的父进程号(译者注:即子进程的父进程号与父进程的父进程号不一样, 父进程号可由getppid函数获得)
  2. 本身的文件描述符和目录流的拷贝(译者注:目录流由opendir函数建立,因其为顺序读取,顾称“目录流”)
  3. 子进程不继承父进程的进程,正文(text), 数据和其它锁定内存(memory locks)(译者注:锁定内存指被锁定的虚拟内存页,锁定后,
  4. 不容许内核将其在必要时换出(page out),详细说明参见《The GNU C Library Reference Manual》 2.2版, 1999, 3.4.2节)
  5. 在tms结构中的系统时间(译者注:tms结构可由times函数得到,它保存四个数据用于记录进程使用中央处理器 (CPU:Central Processing Unit)的时间,包括:用户时间,系统时间, 用户各子进程合计时间,系统各子进程合计时间)
  6. 资源使用(resource utilizations)设定为0
  7. 阻塞信号集初始化为空集(译者注:原文此处不明确,译文根据fork函数手册页稍作修改)
  8. 不继承由timer_create函数建立的计时器
  9. 不继承异步输入和输出

参考:
http://blog.csdn.net/theone10...blog

相关文章
相关标签/搜索