您的位置:首页 > 运维架构 > Linux

linux进程系列(2)进程的继承

2016-11-13 15:40 176 查看
    fork和vfork函数都是涉及到子进程是否复制父进程的虚拟内存空间的问题,这就是进程的继承,下面我们就来讨论一下父进程与子进程的继承关系。

    父进程创建出一个子进程,子进程会继承父进程的一些信息,这些信息我们称之为子进程的继承属性,同时子进程也会有自己特有的属性。

    子进程从父进程继承来的属性主要有:

    用户信息和权限、目录信息、信号信息、环境(也就是环境变量,进程的环境变量保存在环境表中,每个已经启动的进程的环境表都是从父进程的环境表继承下来的)、共享存储段、资源限制、堆、栈和数据段,共享代码段(下文会有介绍)。

    也就是说子进程把上述父进程的内容拷贝一份作为自己使用,这些内容父进程中有一份,子进程中也有一份。但是父进程中有些信息是子进程是复制不了的,也就是属于进程特有的信息,不允许父进程创建的子进程进行复制。这些信息我们称之为进程特有属性:

    进程ID、锁信息、运行时间、未决信号。

    子进程从父进程继承而来的属性中,虚拟内存空间(共享代码段、数据段、堆、栈)的继承比较复杂,对于fork、vfork linux有不同的虚拟内存空间继承机制。下面的图片描述了fork创建的进程,父子进程间虚拟内存空间的继承,p1表示父进程,p2进程表示由p1fork出的子进程。

                 


    每个进程内核都会分配4G的虚拟空间,这4G的虚拟空间包含正文段(代码段)、数据段、堆、栈。这些虚拟空间中的数据会最终映射到物理空间中去,物理空间也就是计算机的内存条。虚拟空间各存储段有各自对应的虚拟地址,这些虚拟地址映射到对应的的物理空间中的物理地址。当fork一个子进程之后,内核也会为子进程分配4G的虚拟地址空间,并且内核会将父进程4G的虚拟空间中内容复制到子进程的4G的虚拟空间中,这样一来父进程4G的内容与子进程4G的内容是一样的。
    对于代码段,父进程中代码段的内容与子进程代码段的内容都是一样的,父进程执行什么样的代码,子进程也会执行什么样的代码。那什么是共享代码段呢?父进程虚拟空间中的代码段映射到的物理空间与子进程虚拟空间中的代码段映射到的物理空间是一样的,这就是上面所说的代码段共享。

    但是父子进程其它的虚拟空间中的其它存储段是不共享的,它们各自映射到自己的物理内存中去。

    对于vfork函数创建一个子进程,虚拟内存空间的继承是这样的:

                                    


     也就是说子进程共享了父进程的虚拟内存空间。

     这样一来我们可以总结出,由fork创建的子进程,在子进程的数据段、堆、栈的内存空间(虚拟内存和物理内存)保留了父进程的原始数据,但是父子进程彼此修改自己的数据互不影响。而vfork创建的子进程完全共享父进程的内存空间(虚拟内存和物理内存),因此父子进程数据段、堆、栈中数据的修改会彼此受到影响。

   另外父子进程,内核空间的继承关系是这样的,操作文件时的内核结构变化:

   子进程只继承父进程的文件描述符表,不继承但共享文件表项和i-node。

   父进程创建一个子进程后,文件表项中的引用计数器加1变成2,当父进程做close操作后,计数器减1,子进程还是可以使用文件表项,只有当计数器为0时才会释放文件表项。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: