天天看点

分析Linux内核创建一个新进程的过程【转】转自:http://www.cnblogs.com/MarkWoo/p/4420588.html前言说明分析

本篇为网易云课堂Linux内核分析课程的第六周作业,本次作业我们将具体来分析<code>fork</code>系统调用,来分析Linux内核创建新进程的过程

*运行环境:**

Ubuntu 14.04 LTS x64

gcc 4.9.2

gdb 7.8

vim 7.4 with vundle

<code>PCB</code>包含了一个进程的重要运行信息,所以我们将围绕在创建一个新进程时,如何来建立一个新的<code>PCB</code>的这一个过程来进行分析,在<code>Linux</code>系统中,<code>PCB</code>主要是存储在一个叫做<code>task_struct</code>这一个结构体中,创建新进程仅能通过<code>fork</code>,<code>clone</code>,<code>vfork</code>等系统调用的形式来进行

不管是<code>fork</code>,还是<code>clone</code>,<code>vfork</code>,他们都是通过<code>do_fork</code>来创建进程

接下来我将通过精简版的<code>do_fork</code>代码,和<code>do_fork</code>中关键的过程来进行分析说明

对于<code>do_fork</code>中比较重要的过程,我已经注释加以说明,这里我抽象的加以把过程总结一边

通过<code>copy_process</code>来复制进程描述符,返回新创建的子进程的task_struct的指针(即PCB指针) 将新创建的子进程放入调度器的队列中,让其有机会获得CPU,并且要确保子进程要先于父进程运行, 这里为什么要确保子进程先于父进程运行呢?,答案是在Linux系统中,有一个叫做copy_on_write技术(写时拷贝技术),该技术的作用是创建新进程时可以减少系统开销,具体该技术的细节请各位Google之,这里子进程先于父进程运行可以保证写时拷贝技术发挥其作用

这里有一个重点的地方需要说明,在使用<code>get_pid</code>系统调用时,返回的并不是进程的<code>pid</code>,而是线程的<code>tgid</code>,<code>tgid</code>指的是一个线程组当时领头的进程的pid

在<code>do_fork</code>中,<code>copy_process</code>函数是比较重要的,其作用是创建进程描述符以及子进程所需要的其他所有数据结构为子进程准备运行环境,下面我将深入<code>copy_process</code>中来详细分析