Linux 核心--5.Linux进程( 七 )



复制完成后 , Linux允许两个进程共享资源而不是复制各自的拷贝 。这些资源包括文件、信号处理过程和虚拟内存 。进程对共享资源用各自的count来记数 。在两个进程对资源的使用完毕之前 , Linux绝不会释放此资源 , 例如复制进程要共享虚拟内存 , 则其task_struct将包含指向原来进程的mm_struct的指针 。mm_struct将增加count变量以表示当前进程共享的次数 。

复制进程虚拟空间所用技术的十分巧妙 。复制将产生一组新的vm_area_struct结构和对应的mm_struct结构 , 同时还有被复制进程的页表 。该进程的任何虚拟内存都没有被拷贝 。由于进程的虚拟内存有的可能在物理内存中 , 有的可能在当前进程的可执行映象中 , 有的可能在交换文件中 , 所以拷贝将是一个困难且繁琐的工作 。Linux使用一种"copy on write"技术:仅当两个进程之一对虚拟内存进行写操作时才拷贝此虚拟内存块 。但是不管写与不写 , 任何虚拟内存都可以在两个进程间共享 。只读属性的内存 , 如可执行代码 , 总是可以共享的 。为了使"copy on write"策略工作 , 必须将那些可写区域的页表入口标记为只读的 , 同时描叙它们的vm_area_struct数据都被设置为"copy on write" 。当进程之一试图对虚拟内存进行写操作时将产生页面错误 。这时Linux将拷贝这一块内存并修改两个进程的页表以及虚拟内存数据结构 。


4.7时钟和定时器
核心跟踪着进程的创建时间以及在其生命期中消耗的CPU时间 。每个时钟滴答时 , 核心将更新当前进程在系统 模式与用户模式下所消耗的时间(记录在jiffies中) 。
除了以上记时器外 , Linux还支持几种进程相关的时间间隔定时器 。

进程可以使用这些定时器在到时时向它发送各种信号 , 这些定时器如下:


Real
此定时器按照实时时钟记数 , 当时钟到期时 , 向进程发送SIGALRM信号 。
Virtual
此定时器仅在进程运行时记数 , 时钟到期时将发送SIGVTALRM信号 。
Profile
此定时器在进程运行和核心为其运行时都记数 。当到时时向进程发送SIGPROF信号 。
以上时间间隔定时器可以同时也可以单独运行 , Linux将所有这些信息存储在进程的task_struct数据结构中 。通过系统调用可以设置这些时间间隔定时器并启动、终止它们或读取它们的当前值 。Virtual和Profile定时器以相同方式处理 。

每次时钟滴答后当前进程的时间间隔定时器将递减 , 当到时之后将发送适当的信号 。

Real时钟间隔定时器的机制有些不同 , 这些将在kernel一章中详细讨论 。每个进程有其自身的timer_list数 据结构 , 当时间间隔定时器运行时 , 它们被排入系统的定时器链表中 。当定时器到期后 , 底层处理过程将把它从队列中删除并调用时间间隔处理过程 。此过程将向进程发送SIGALRM信号并重新启动定时器 , 将其重新放入系统时钟队列 。



4.8程序执行
象Unix一样 , Linux程序通过命令解释器来执行 。命令解释器是一个用户进程 , 人们将其称为shell程序 。

在Linux中有多个shell程序 , 最流行的几个是sh、bash和tcsh 。除了几个内置命令如cd和pwd外 , 命令都是 一个可执行二进制文件 。当键入一个命令时 , Shell程序将搜索包含在进程PATH环境变量中查找路径中的目 录来定位这个可执行映象文件 。如果找到 , 则它被加载且执行 。shell使用上面描叙的fork机制来复制自身 然后用找到的二进制可执行映象的内容来代替其子进程 。一般情况下 , shell将等待此命令的完成或者子进 程的退出 。你可以通过按下control-Z键使子进程切换到后台而shell再次开始运行 。同时还可以使用shell 命令bg将命令放入后台执行 , shell将发送SIGCONT信号以重新启动进程直到进程需要进行终端输出和输入 。

推荐阅读