操做系统(三)

3.1 什么是进程

3.1.1 背景

在给进程下定义以前,先总结一下第一、2章介绍的一些概念:算法

  • 一个计算机平台包括一组硬件资源,好比处理器、内存、I/O 模块、定时器和磁盘驱动器等。
  • 计算机程序是为执行某些任务而开发的。在典型的状况下,它们接受外来的输入,作一些处理以后,输出结果。
  • 直接根据给定的硬件平台写应用程序效率是低下的,主要缘由以下:
    • 针对相同的平台能够开发出不少应用程序,因此开发出这些应用程序访问计算机资源的通用例程是颇有意义的。
    • 处理器自己只能对多道程序设计提供有限的支持,须要用软件去管理处理器和其余资源同时被多个程序共享。
    • 若是多个程序在同一时间都是活跃的,那么须要保护每一个程序的数据、I/O 使用和其余资源不被其余程序占用。
  • 开发操做系统是为了给应用程序提供一个方便、安全和一致的接口。操做系统是计算机硬件和应用程序之间的一层软件,对应用程序和工具提供了支持。
  • 能够把操做系统想象为资源的统一抽象表示,能够被应用程序请求和访问。资源包括内存、网络接口和文件系统等。一旦操做系统为应用程序建立了这些资源的抽象表示,就必须管理它们的使用,例如一个操做系统能够容许资源共享和资源保护。

有了应用程序、系统软件和资源的概念,就能够讨论操做系统怎样以一个有序的方式管理应用程序的执行,以达到如下目的:数据库

  • 资源对多个应用程序是可用的。
  • 物理处理器在多个应用程序间切换以保证全部程序都在执行中。
  • 处理器和I/O 设备能获得充分的利用。

全部现代操做系统采用的方法都是依据对应于一个或多个进程存在的应用程序执行的一种模型。小程序

3.1.2 进程和进程控制块

第2章给进程下了如下几个定义:安全

  • 正在执行的程序。
  • 正在计算机上执行的程序实例。
  • 能分配给处理器并由处理器执行的实体。
  • 具备如下特征的活动单元:一组指令序列的执行、一个当前状态和相关的系统资源集。

也能够把进程当成由一组元素组成的实体,进程的两个基本的元素是程序代码(可能被执行相同程序的其余进程共享)和代码相关联的数据集。
假设处理器开始执行这个程序代码,且把这个执行实体叫作进程。
在进程执行时,任意给定一个时间,进程均可以惟一地被表征为如下元素:服务器

  • 标识符:跟这个进程相关的惟一标识符,用来区别其余进程。
  • 状态:若是进程正在执行,那么进程处于运行态。
  • 优先级:相对于其余进程的优先级。
  • 程序计数器:程序中即将被执行的下一条指令的地址。
  • 内存指针:包括程序代码和进程相关数据的指针,还有和其余进程共享内存块的指针。
  • 上下文数据:进程执行时处理器的寄存器中的数据。
  • I/O 状态信息:包括显式的I/O 请求、分配给进程的I/O 设备(例如磁带驱动器)和被进程使用的文件列表等。
  • 记帐信息:可能包括处理器时间总和、使用的时钟数总和、时间限制、记帐号等。

上述列表信息存放在一个叫作进程控制块(如图)的数据结构中,该控制块由操做系统建立和管理。进程控制块包含了充分的信息,这样就能够中断一个进程的执行,而且在后来恢复执行进程时就好像进程未被中断过。进程控制块是操做系统可以支持多进程和提供多处理的关键工具。当进程被中断时,操做系统会把程序计数器和处理器寄存器(上下文数据)保存到进程控制块中的相应位置,进程状态也被改变为其余的值,例如阻塞态或就绪态(后面将讲述)。操做系统能够把其余进程设置为运行态,把其余进程的程序计数器和进程上下文数据加载处处理器寄存器中,这样其余进程就能够开始执行了。网络

 
图3.1 简化的进程控制块

所以,进程是由程序代码和相关数据还有进程控制块组成。对于一个单处理器计算机,在任什么时候间都最多只有一个进程在执行,正在运行的这个进程的状态为运行态。数据结构

3.2 进程状态

正如前面所提到的,对一个被执行的程序,操做系统会为该程序建立一个进程或任务。并发

  • 从处理器的角度看,它在指令序列中按某种顺序执行指令,这个顺序根据程序计数器寄存器中不断变化的值来指示,程序计数器可能指向不一样进程中不一样部分的程序代码;
  • 从程序自身的角度看,它的执行涉及程序中的一系列指令。能够经过列出为该进程执行的指令序列来描述单个进程的行为,这样的序列称作进程的轨迹。能够经过给出各个进程的轨迹是如何被交替的来描述处理器的行为。

举例,图3.2 给出了三个进程在内存中的布局,为简化讨论,假设没有使用虚拟内存,所以全部三个进程都由彻底载入内存中的程序表示,此外,有一个小的分派器一1使处理器从一个进程切换到另外一个进程。图3.3 给出了这三个进程在执行过程早期的轨迹,给出了进程A 和C 中最初执行的12 条指令,进程B 执行4 条指令,假设第4 条指令调用了进程必须等待的I/O 操做。编辑器

 
图3.2 在指令周期13 时的执
行快照(如图3.4 所示)

如今从处理器的角度看这些轨迹。图3.4 给出了最初的52个指令周期中交替的轨迹(为方便起见,指令周期都给出了编号)。在图中,阴影部分表明由分配器执行的代码。在每一个实例中由分派器执行的指令顺序是相同的,由于是分派器的同一个功能在执行。假设操做系统仅容许一个进程最多连续执行6 个指令周期,在此以后将被中断,这避免了任何一个进程独占处理器时间。如图3.4 所示,进程A 最初的6 条指令被执行,接下来是一个超时并执行分派器的某些代码,在控制转移给进程B 以前分派器执行了6 条指令二2。在进程B 的4 条指令被执行后,进程B 请求一个它必须等待的I/O 动做,所以,处理器中止执行进程B,并经过分派器转移到进程C。在超时后,处理器返回进程A,当此次处理超时时,进程B 仍然等待那个I/O 操做的完成,所以分派器再次转移到进程C。模块化

 
(点击查看大图)图3.3 图3.2 中进程的轨迹
 
(点击查看大图)图3.4 图3.2 中进程的组合轨迹

3.2.1 两状态进程模型

操做系统的基本职责是控制进程的执行,这包括肯定交替执行的方式和给进程分配资源。在设计控制进程的程序时,第一步就是描述进程所表现出的行为。

任什么时候刻,一个进程能够处于如下两种状态之一:运行态或未运行态,如图3.5a 所示。当操做系统建立一个新进程时,它将该进程以未运行态加入到系统中,操做系统知道这个进程是存在的,并正在等待执行机会。当前正在运行的进程不时地被中断,操做系统中的分派器部分将选择一个新进程运行。前一个进程从运行态转换到未运行态,另一个进程转换到运行态。

从这个简单的模型能够意识到操做系统的一些设计元素。必须用某种方式来表示每一个进程,使得操做系统可以跟踪它,也就是说,必须有一些与进程相关的信息,包括进程在内存中的当前状态和位置,即进程控制块。未运行的进程必须保持在某种类型的队列中,并等待它们的执行时机。图3.5b 给出了一个结构,结构中有一个队列,队列中的每一项都指向某个特定进程的指针,或队列能够由数据块构成的链表组成,每一个数据块表示一个进程。

能够用该排队图描述分派器的行为。被中断的进程转移到等待进程队列中,或者,若是进程已经结束或取消,则被销毁(离开系统)。在任何一种状况下,分派器均从队列中选择一个进程来执行。

 
图3.5 两状态进程模型

3.2.2 进程的建立和终止

在对简单的两状态模型进行改进以前,讨论一下进程的建立和终止。不管使用哪一种进程行为模型,进程的生存期都围绕着进程的建立和终止。

进程的建立

当一个新进程添加到那些正在被管理的进程集合中去时,操做系统须要创建用于管理该进程的数据结构(见3.3 节),并在内存中给它分配地址空间。将在3.3 节中讲述这些数据结构,这些行为构成了一个新进程的建立过程。

一般有4 个事件会致使建立一个进程,如表。

  • 在批处理环境中,响应做业提交时会建立进程;
  • 在交互环境中,当一个新用户试图登陆时会建立进程。

不论在哪一种状况下,操做系统都负责新进程的建立;操做系统也可能会表明应用程序建立进程,eg:若是用户请求打印一个文件,则操做系统能够建立一个管理打印的进程,进而使请求进程能够继续执行,与完成打印任务的时间无关。

表3.1 致使进程建立的缘由

 

传统地,操做系统建立进程的方式对用户和应用程序都是透明的。但容许一个进程引起另外一个进程的建立将是颇有用的。例如,一个应用程序进程能够产生另外一个进程,以接收应用程序产生的数据,并将数据组织成适合之后分析的格式。新进程与应用程序并行地运行,并当获得新的数据时被激活。这个方案对构造应用程序是很是有用的,例如,服务器进程(如打印服务器、文件服务器)能够为它处理的每一个请求产生一个新进程。当操做系统为另外一个进程的显式请求建立一个进程时,这个动做称为进程派生

当一个进程派生另外一个进程时,前一个称作父进程,被派生的进程称作子进程。在典型的状况下,相关进程须要相互之间的通讯和合做。相关主题将在第5 章讲述。

进程终止

表3.2 归纳了进程终止的典型缘由。任何一个计算机系统都必须为进程提供表示其完成的方法,批处理做业中应该包含一个Halt 指令或用于终止的操做系统显式服务调用来终止。

  • Halt 指令将产生一个中断,警告操做系统一个进程已经完成。
  • 对交互式应用程序,用户的行为将指出什么时候进程完成,例如,在分时系统中,当用户退出系统或关闭本身的终端时,该用户的进程将被终止。在我的计算机或工做站中,用户能够结束一个应用程序(如字处理或电子表格)。全部这些行为最终致使发送给操做系统的一个服务请求,以终止发出请求的进程。
  • 此外,不少错误和故障条件会致使进程终止。表3.2 列出了一些最多见的识别条件。
  • 最后,在有些操做系统中,进程能够被建立它的进程终止,或当父进程终止时而终止。

表3.2 致使进程终止的缘由

 

3.2.3 五状态模型

若是全部进程都作好了执行准备,则图3.5b 所给出的排队原则是有效的。队列是“先进先出”的表,对于可运行的进程处理器以一种轮转方式操做(依次给队列中的每一个进程必定的执行时间,而后进程返回队列,阻塞状况除外)。但即便对前面描述的简单例子,这个实现都是不合适的:存在着一些处于非运行状态但已经就绪等待执行的进程,而同时存在另外的一些处于阻塞状态等待I/O 操做结束的进程。所以,若是使用单个队列,分派器不能只考虑选择队列中最老的进程,相反,它应该扫描这个列表,查找那些未被阻塞且在队列中时间最长的进程

解决这种状况的一种比较天然的方法是将非运行状态分红两个状态:就绪(ready)和阻塞(blocked),以下图。新图中的5 个状态以下:

 
图3.6 五状态进程模型
  • 运行态:该进程正在执行。在本章中,假设计算机只有一个处理器,所以一次最多只有一个进程处于这个状态。
  • 就绪态:进程作好了准备,只要有机会就开始执行。
  • 阻塞/等待态:进程在某些事件发生前不能执行,如I/O 操做完成。
  • 新建态:刚刚建立的进程,操做系统尚未把它加入到可执行进程组中。一般是进程控制块已经建立但尚未加载到内存中的新进程。
  • 退出态:操做系统从可执行进程组中释放出的进程,或者是由于它自身中止了,或者是由于某种缘由被取消。

新建状态对应于刚刚定义的进程。例如,若是一位新用户试图登陆到分时系统中,或者一个新的批做业被提交执行,那么操做系统能够分两步定义新进程。

  • 首先,操做系统执行一些必需的辅助工做,将标识符关联到进程,分配和建立管理进程所须要的全部表。此时,进程处于新建状态,这意味着操做系统已经执行了建立进程的必需动做,但尚未执行进程。例如,操做系统可能基于性能或内存局限性的缘由,限制系统中的进程数量。当进程处于新建态时,操做系统所须要的关于该进程的信息保存在内存中的进程表中,但进程自身还未进入内存,就是即将执行的程序代码不在内存中,也没有为与这个程序相关的数据分配空间。当进程处于新建态时,程序保留在外存中,一般是磁盘中。

相似地,进程退出系统也分为两步。

  • 首先,当进程到达一个天然结束点时,因为出现不可恢复的错误而取消时,或当具备相应权限的另外一个进程取消该进程时,进程被终止;终止使进程转换到退出态,此时,进程再也不被执行了,与做业相关的表和其余信息临时被操做系统保留起来,这给辅助程序或支持程序提供了提取所需信息的时间。一个实用程序为了分析性能和利用率,可能须要提取进程的历史信息,一旦这些程序都提取了所须要的信息,操做系统就再也不须要保留任何与该进程相关的数据,该进程将从系统中删除。

图3.6 显示了致使进程状态转换的事件类型。可能的转换以下:

  • 空→新建:建立执行一个程序的新进程。这个事件在表3.1 中所列出的缘由下都会发生。
  • 新建→就绪:操做系统准备好再接纳一个进程时,把一个进程重新建态转换到就绪态。大多数系统基于现有的进程数或分配给现有进程的虚拟内存数量设置一些限制,以确保不会由于活跃进程的数量过多而致使系统的性能降低。
  • 就绪→运行:须要选择一个新进程运行时,操做系统选择一个处于就绪态的进程,这是调度器或分派器的工做。进程的选择问题将在第四部分探讨。
  • 运行→退出:若是当前正在运行的进程表示本身已经完成或取消,则它将被操做系统终止,见表3.2。
  • 运行→就绪:这类转换最多见的缘由是,正在运行的进程到达了“容许不中断执行”的最大时间段;实际上全部多道程序操做系统都实行了这类时间限定。这类转换还有不少其余缘由,例如操做系统给不一样的进程分配不一样的优先级,但这不是在全部的操做系统中都实现了的。假设,进程A 在一个给定的优先级运行,且具备更高优先级的进程B 正处于阻塞态。若是操做系统知道进程B 等待的事件已经发生了,则将B 转换到就绪态,而后由于优先级的缘由中断进程A 的执行,将处理器分派给进程B,咱们说操做系统抢占了进程A。最后一种状况是,进程自愿释放对处理器的控制,例如一个周期性地进行记帐和维护的后台进程。
  • 运行→阻塞:若是进程请求它必须等待的某些事件,则进入阻塞态。对操做系统的请求一般以系统服务调用的形式发出,也就是说,正在运行的程序请求调用操做系统中一部分代码所发生的过程。例如,进程可能请求操做系统的一个服务,但操做系统没法当即予以服务,它也可能请求了一个没法当即获得的资源,如文件或虚拟内存中的共享区域;或者也可能须要进行某种初始化的工做,如I/O 操做所遇到的状况,而且只有在该初始化动做完成后才能继续执行。当进程互相通讯,一个进程等待另外一个进程提供输入时,或者等待来自另外一个进程的信息时,均可能被阻塞。
  • 阻塞→就绪:当所等待的事件发生时,处于阻塞态的进程转换到就绪态。
  • 就绪→退出:为了清楚起见,状态图中没有表示这种转换。在某些系统中,父进程能够在任什么时候刻终止一个子进程。若是一个父进程终止,与该父进程相关的全部子进程都将被终止。
  • 阻塞→退出:前面一项提供了注释。

再回到前面的简单例子,图3.7 显示了每一个进程在状态间的转换,图3.8a 给出了可能实现的排队规则,有两个队列:就绪队列和阻塞队列。进入系统的每一个进程被放置在就绪队列中,当操做系统选择另外一个进程运行时,将从就绪队列中选择。对于没有优先级的方案,这能够是一个简单的先进先出队列。当一个正在运行的进程被移出处理器时,它根据状况或者被终止,或者被放置在就绪或阻塞队列中。最后,当一个事件发生时,全部位于阻塞队列中等待这个事件的进程都被转换到就绪队列中。

 
图3.7 图3.4 中的进程状态

后一种方案意味着当一个事件发生时,操做系统必须扫描整个阻塞队列,搜索那些等待该事件的进程。在大型操做系统中,队列中可能有几百甚至几千个进程,所以,拥有多个队列将会颇有效,一个事件能够对应一个队列。那么,当事件发生时,相应队列中的全部进程都转换到就绪态(见图3.8b)。

 
(点击查看大图)图3.8 图3.6 的排队模型

最后还有一种改进是,若是按照优先级方案分派进程,维护多个就绪队列(每一个优先级一个队列)将会带来不少的便利。操做系统能够很容易地肯定哪一个就绪进程具备最高的优先级且等待时间最长。

3.2.4 被挂起的进程

交换的须要

前面描述的三个基本状态(就绪态、运行态和阻塞态)提供了一种为进程行为创建模型的系统方法,但能够证实往模型中增长其余状态也是合理的。为了说明加入新状态的好处,考虑一个没有使用虚拟内存的系统,每一个被执行的进程必须彻底载入内存,所以,图3.8b 中,全部队列中的全部进程必须驻留在内存中。

全部这些设计机制的缘由都是因为I/O 活动比计算速度慢不少,所以在单道程序系统中的处理器在大多数时候是空闲的。可是图3.8b 的方案并无彻底解决这个问题。在这种状况下,内存保存有多个进程,当一个进程正在等待时,处理器能够转移到另外一个进程,可是处理器比I/O要快得多,以致于内存中全部的进程都在等待I/O 的状况很常见。所以,即便是多道程序设计,大多数时候处理器仍然可能处于空闲状态。

一种解决方法是内存能够被扩充以适应更多的进程,可是这种方法有两个缺陷。

  • 首先是内存的价格问题,当内存大小增长到兆位及千兆位时,价格也会随之增长;
  • 再者,程序对内存空间需求的增加速度比内存价格降低的速度快。所以,更大的内存每每致使更大的进程,而不是更多的进程。

另外一种解决方案是交换,包括把内存中某个进程的一部分或所有移到磁盘中。当内存中没有处于就绪状态的进程时,操做系统就把被阻塞的进程换出到磁盘中的“挂起队列”。操做系统在此以后取出挂起队列中的另外一个进程,或者接受一个新进程的请求,将其归入内存运行。进程行为模型(见图3.9a)中增长另外一个状态:挂起态。

“交换”是一个I/O 操做,于是也可能使问题更加恶化。可是因为磁盘I/O 通常是系统中最快的I/O(相对于磁带或打印机I/O),因此交换一般会提升性能。

当操做系统已经执行了一个换出操做,它能够有两种将一个进程取到内存中的选择:

  • 能够接纳一个新近建立的进程;
  • 或调入一个之前被挂起的进程。

一般比较倾向于调入一个之前被挂起的进程,给它提供服务,而不是增长系统中的负载总数。

但全部已经挂起的进程在挂起时都处于阻塞态。显然,这时把被阻塞的进程取回内存没有任何意义,由于它仍然没有准备好执行。可是,挂起状态中的每一个进程最初是阻塞在一个特定的事件上,当这个事件发生时,进程就再也不阻塞,能够继续执行。所以,须要从新考虑设计方式。有两个独立的概念:进程是否在等待一个事件(阻塞与否)以及进程是否已经被换出内存(挂起与否)。为适应这种2×2 的组合,须要4 个状态:

  • 就绪态:进程在内存中并能够执行。
  • 阻塞态:进程在内存中并等待一个事件。
  • 阻塞/挂起态:进程在外存中并等待一个事件。
  • 就绪/挂起态:进程在外存中,可是只要被载入内存就能够执行。
 
图3.9 有挂起态的进程状态转换图

在查看包含两个新挂起状态的状态转换图以前,必须提到另外一点。到如今为止的论述都假设没有使用虚拟内存,进程或者都在内存中,或者都在内存以外。在虚拟内存方案中,可能会执行到只有一部份内容在内存中的进程,若是访问的进程地址不在内存中,则进程的相应部分能够被调入内存。虚拟内存的使用看上去会消除显式交换的须要,这是由于经过处理器中的存储管理硬件,任何指望的进程中的任何指望的地址均可以移入或移出内存。可是,正如在第8 章中将会看到的,若是有足够多的活动进程,而且全部进程都有一部分在内存中,则有可能致使虚拟内存系统崩溃。所以,即便在虚拟存储系统中,操做系统也须要不时地根据执行状况显式地、彻底地换出进程。

如今来看图3.9b 中咱们已开发的状态转换模型(图中的虚线表示可能但并非必需的转换)。比较重要的新的转换以下:

  • 阻塞→阻塞/挂起:若是没有就绪进程,则至少一个阻塞进程被换出,为另外一个没有阻塞的进程让出空间。若是操做系统肯定当前正在运行的进程,或就绪进程为了维护基本的性能要求而须要更多的内存空间,那么,即便有可用的就绪态进程也可能出现这种转换。
  • 阻塞/挂起→就绪/挂起:若是等待的事件发生了,则处于阻塞/挂起状态的进程能够转换到就绪/挂起状态。注意,这要求操做系统必须可以获得挂起进程的状态信息。
  • 就绪/挂起→就绪:若是内存中没有就绪态进程,操做系统须要调入一个进程继续执行。此外,当处于就绪/挂起态的进程比处于就绪态的任何进程的优先级都要高时,也能够进行这种转换。这种状况的产生是因为操做系统设计者规定调入高优先级的进程比减小交换量更重要。
  • 就绪→就绪/挂起:一般,操做系统更倾向于挂起阻塞态进程而不是就绪态进程,由于就绪态进程能够当即执行,而阻塞态进程占用了内存空间但不能执行。但若是释放内存以获得足够空间的惟一方法是挂起一个就绪态进程,那么这种转换也是必需的。而且,若是操做系统确信高优先级的阻塞态进程很快将会就绪,那么它可能选择挂起一个低优先级的就绪态进程,而不是一个高优先级的阻塞态进程。

还须要考虑的几种其余转换有:

  • 新建→就绪/挂起以及新建→就绪:当建立一个新进程时,该进程或者加入到就绪队列,或者加入到就绪/挂起队列中。不论哪一种状况,操做系统都必须创建一些表以管理进程,并为进程分配地址空间。操做系统可能更倾向于在初期执行这些辅助工做,这使得它能够维护大量的未阻塞的进程。经过这个策略,内存中常常会没有足够的空间分配给新进程,所以使用了(新建→就绪/挂起)转换。另外一方面,咱们能够证实建立进程的适时(just-in-time)原理,即尽量推迟建立进程以减小操做系统的开销,并在系统被阻塞态进程阻塞时容许操做系统执行进程建立任务。
  • 阻塞/挂起→阻塞:这种转换在设计中比较少见,若是一个进程没有准备好执行,而且不在内存中,调入它又有什么意义?可是考虑到下面的状况:一个进程终止,释放了一些内存空间,阻塞/挂起队列中有一个进程比就绪/挂起队列中的任何进程的优先级都要高,而且操做系统有理由相信阻塞进程的事件很快就会发生,这时,把阻塞进程而不是就绪进程调入内存是合理的。
  • 运行→就绪/挂起:一般当分配给一个运行进程的时间期满时,它将转换到就绪态。可是,若是因为位于阻塞/挂起队列的具备较高优先级的进程变得再也不被阻塞,操做系统抢占这个进程,也能够直接把这个运行进程转换到就绪/挂起队形中,并释放一些内存空间。
  • 各类状态→退出:在典型状况下,一个进程在运行时终止,或者是由于它已经完成,或者是由于出现了一些错误条件。可是,在某些操做系统中,一个进程能够被建立它的进程终止,或当父进程终止时终止。若是容许这样,则进程在任何状态时均可以转换到退出态。

挂起的其余用途

到目前为止,挂起进程的概念与不在内存中的进程概念是等价的一个不在内存中的进程,不论它是否在等待一个事件,都不能当即执行。

咱们能够总结一下挂起进程的概念。首先,按照如下特色定义挂起进程:

  1. 进程不能当即执行。
  2. 进程多是或不是正在等待一个事件。若是是,阻塞条件不依赖于挂起条件,阻塞事件的发生不会使进程当即被执行。
  3. 为阻止进程执行,能够经过代理把这个进程置于挂起状态,代理能够是进程本身,也能够是父进程或操做系统。
  4. 除非代理显式地命令系统进行状态转换,不然进程没法从这个状态中转移。

表3.3 列出了进程的一些挂起缘由。

  • 提供更多的内存空间,这样能够调入一个就绪/挂起态进程或增长分配给其余就绪态进程的内存;
  • 操做系统由于其余动机而挂起一个进程,例如,记帐或跟踪进程可能用于监视系统的活动,可使用进程记录各类资源(处理器、内存、通道)的使用状况以及系统中用户进程的进行速度。在操做员控制下的操做系统能够不时地打开或关闭这个进程。
  • 若是操做系统发现或怀疑有问题,它能够挂起进程。死锁就是一个例子,将在第6 章讲述。
  • 另外一个例子是,若是在进程测试时检测到通讯线路中的问题,操做员让操做系统挂起使用该线路的进程。

另一些缘由关系到交互用户的行为。例如,若是用户怀疑程序中有缺陷,他(她)能够挂起执行程序并进行调试,检查并修改程序或数据,而后恢复执行;或者可能有一个收集记录或记帐的后台程序,用户可能但愿可以打开或关闭这个程序。

表3.3 致使进程挂起的缘由

 

时机的选择也会致使一个交换决策。例如,若是一个进程周期性地被激活,但大多数时间是空闲的,则在它在两次使用之间应该被换出。监视使用状况或用户活动的程序就是一个例子。

最后,父进程可能会但愿挂起一个后代进程。例如,进程A 能够生成进程B,以执行文件读操做;随后,进程B 在读文件的过程当中遇到错误,并报告给进程A;进程A 挂起进程B,调查错误的缘由。

在全部这些状况中,挂起进程的活动都是由最初请求挂起的代理请求的。

3.3 进程描述

操做系统控制计算机系统内部的事件,它为处理器执行进程而进行调度和分派,给进程分配资源,并响应用户程序的基本服务请求。所以,咱们能够把操做系统看作是管理系统资源的实体。

这个概念如图3.10 所示。在多道程序设计环境中,在虚拟内存中有许多已经建立了的进程,每一个进程在执行期间,须要访问某些系统资源,包括处理器、I/O 设备和内存。在图中,进程P1 正在运行,该进程至少有一部分在内存中,而且还控制着两个I/O 设备;进程P2 也在内存中,但因为正在等待分配给P1 的I/O 设备而被阻塞;进程Pn 已经被换出,所以是挂起的。

之后几章中将探讨操做系统表明进程管理这些资源的细节。这里关心的是一些最基本的问题:操做系统为了控制进程和管理资源须要哪些信息?

 
图3.10 进程和资源(某一时刻的资源分配)

3.3.1 操做系统的控制结构

操做系统为了管理进程和资源,必须掌握关于每一个进程和资源当前状态的信息。广泛使用的方法是:操做系统构造并维护它所管理的每一个实体的信息表。如图3.11,操做系统维护着4 种不一样类型的表:内存、I/O、文件和进程

 
图3.11 操做系统控制表的通用结构

1、内存表用于跟踪内(实)存和外存(虚拟内存)。内存的某些部分为操做系统而保留,剩余部分是进程可使用的,保存在外存中的进程使用某种类型的虚拟内存或简单的交换机制。内存表必须包括如下信息:

  • 分配给进程的内存。
  • 分配给进程的外存。
  • 内存块或虚拟内存块的任何保护属性,如哪些进程能够访问某些共享内存区域。
  • 管理虚拟内存所须要的任何信息。

第三部分将详细讲述用于内存管理的信息结构。

2、操做系统使用I/O 表管理计算机系统中的I/O 设备和通道。在任何给定的时刻,一个I/O 设备或者是可用的,或者已分配给某个特定的进程,若是正在进行I/O 操做,则操做系统须要知道I/O 操做的状态和做为I/O 传送的源和目标的内存单元。在第11 章将详细讲述I/O 管理。

3、操做系统维护着文件表,这些表提供关于文件是否存在、文件在外存中的位置、当前状态和其余属性的信息。大部分信息(不是所有信息)可能由文件管理系统维护和使用。在这种状况下,操做系统只有一点或者没有关于文件的信息;在其余操做系统中,不少文件管理的细节由操做系统本身管理。这方面的内容将在第12 章讲述。

4、最后,操做系统为了管理进程必须维护进程表。须要先明确两点:首先,尽管图3.11 给出了4 种不一样的表,可是这些表必须以某种方式连接起来或交叉引用。内存、I/O 和文件是表明进程而被管理的,所以进程表中必须有对这些资源的直接或间接引用。文件表中的文件能够经过I/O 设备访问,有时它们也位于内存中或虚拟内存中。这些表自身必须能够被操做系统访问到,所以它们受制于内存管理。

其次,操做系统最初如何知道建立表?显然,操做系统必须有基本环境的一些信息,若有多少内存空间、I/O 设备是什么以及它们的标识符是什么等。这是一个配置问题,也就是说,当操做系统初始化后,它必须可使用定义基本环境的某些配置数据,这些数据必须在操做系统以外,经过人的帮助或一些自动配置软件而产生。

3.3.2 进程控制结构

操做系统在管理和控制进程时,首先必须知道进程的位置以及在管理时所必需的进程属性(如进程ID、进程状态)。

进程位置

进程的物理表示是什么?

  • 进程最少必须包括一个或一组被执行的程序,与这些程序相关联的是局部变量、全局变量和任何已定义常量的数据单元。所以,一个进程至少包括足够的内存空间,以保存该进程的程序和数据;
  • 此外,程序的执行一般涉及用于跟踪过程调用和过程间参数传递的(见附录1B)。
  • 最后,与每一个进程相关联的还有操做系统用于控制进程的许多属性,一般,属性的集合称作进程控制块。

程序、数据、栈和属性的集合称作进程映像(process image)(见表3.4进程映像中的典型元素)。

 

进程映像的位置依赖于使用的内存管理方案。
最简单的状况,进程映像保存在邻近的或连续的存储块中。该存储块位于外存(一般是磁盘)中。若是操做系统要管理进程,其进程映像至少有一部分必须位于内存中,为执行该进程,整个进程映像必须载入内存中或至少载入虚拟内存中。所以,操做系统须要知道每一个进程在磁盘中的位置,而且对于内存中的每一个进程,须要知道其在内存中的位置。来看一下第2 章中CTSS 操做系统关于这个方案的一个稍微复杂些的变体。在CTSS 中,当进程被换出时,部分进程映像可能保留在内存中。所以,操做系统必须跟踪每一个进程映像的哪一部分仍然在内存中。

现代操做系统假定分页硬件容许用不连续的物理内存来支持部分常驻内存的进程。在任何给定的时刻,进程映像的一部分能够在内存中,剩余部分能够在外存中。所以,操做系统维护的进程表必须代表每一个进程映像中每页的位置。

图3.11 描绘了位置信息的结构。有一个主进程表,每一个进程在表中都有一个表项,每一项至少包含一个指向进程映像的指针。若是进程映像包括多个块,则这个信息直接包含在主进程表中,或能够经过交叉引用内存表中的项获得。固然,这个描述是通常性描述,特定的操做系统将按本身的方式组织位置信息。

进程属性

每一个进程的大量信息该信息能够保留在进程控制块中。不一样的系统以不一样的方式组织该信息。表3.5( 进程控制块中的典型元素) 列出了每一个进程信息的简单分类。

能够把进程控制块信息分红三类:

  • 进程标识信息
  • 处理器状态信息
  • 进程控制信息
 
 

1、每一个进程都分配了一个惟一的数字标识符。进程标识符能够简单地表示为主进程表(图3.11 所示)中的一个索引;不然,必须有一个映射,使得操做系统能够根据进程标识符定位相应的表。操做系统控制的许多其余表可使用进程标识符交叉引用进程表。例如,内存表能够组织起来以便提供一个关于内存的映射,指明每一个区域分配给了哪一个进程。I/O 表和文件表中也会有相似的引用。当进程相互之间进行通讯时,进程标识符可用于通知操做系统某一特定通讯的目标;当容许进程建立其余进程时,标识符可用于指明每一个进程的父进程和后代进程。

除了进程标识符,还给进程分配了一个用户标识符,用于标明拥有该进程的用户。

2、处理器状态信息包括处理器寄存器的内容。当一个进程正在运行时,其信息固然在寄存器中。当进程被中断时,全部的寄存器信息必须保存起来,使得进程恢复执行时这些信息均可以被恢复。所涉及的寄存器的种类和数目取决于处理器的设计。在典型状况下,寄存器组包括用户可见寄存器、控制和状态寄存器和栈指针,这些在第1 章中都曾介绍过。

处理器都包括一个或一组一般称作程序状态字( PSW)的寄存器,它包含状态信息。PSW 一般包含条件码和其余状态信息。Pentium处理器中的处理器状态字就是一个很好的例子,它称作EFLAGS 寄存器(如图3.12 和表3.6 所示),可被运行在Pentium 处理器上的任何操做系统(包括UNIX 和Windows)使用。

3、进程控制信息是操做系统控制和协调各类活动进程所须要的额外信息。表3.5 代表了这类信息的范围,随后章节将进一步详细分析。

图3.13 给出了虚拟内存中进程映像的结构。每一个进程映像包括一个进程控制块、用户栈、进程的专用地址空间以及与别的进程共享的任何其余地址空间。在这个图中,每一个进程映像表现为一段地址相邻的区域。在实际的实现中可能不是这种状况,这取决于内存管理方案和操做系统组织控制结构的方法。

 
图3.12 PentiumⅡEFLAGS 寄存器

表3.6 Pentium EFLAGS 寄存器位

 

正如表3.5 中所指出的,进程控制块还可能包含构造信息,包括将进程控制块连接起来的指针。所以,前一节中所描述的队列能够由进程控制块的链表实现,例如,图3.8a 中的排队结构能够按图3.14 中的方式实现。

进程控制块的做用

每一个进程控制块包含操做系统所须要的关于进程的全部信息。实际上,操做系统中的每一个模块,包括那些涉及调度、资源分配、中断处理、性能监控和分析的模块,均可能读取和修改它们。能够说,资源控制块集合定义了操做系统的状态。

 
(点击查看大图)图3.13 虚拟内存中的用户进程

操做系统中的不少例程都须要访问进程控制块中,直接访问这些表并不难,每一个进程都有一个惟一ID 号,可用做进程控制块指针表的索引。困难的不是访问而是保护,具体表现为下面两个问题:

  • 一个例程(如中断处理程序)中有错误,可能会破坏进程控制块,进而破坏了系统对受影响进程的管理能力。
  • 进程控制块的结构或语义的设计变化可能会影响到操做系统中的许多模块。

这些问题能够经过要求操做系统中的全部例程都经过一个处理例程来专门处理,处理例程的任务仅仅是保护进程控制块,它是读写这些块的惟一的仲裁程序。使用这类进程,须要权衡性能问题和对系统软件剩余部分正确性的信任程度。

 

图3.14 进程链表结构

3.4 进程控制

3.4.1 执行模式

首先需区分“与操做系统相关联的”以及“与用户程序相关联”的处理器执行模式。
某些指令只能在特权态下运行,包括读取或改变诸如程序状态字之类控制寄存器的指令、原始I/O 指令和与内存管理相关的指令。另外,有部份内存区域仅在特权态下能够被访问到。

  • 非特权态常称作用户态,用户程序一般在该模式下运行;
  • 特权态可称作系统态、控制态或内核态,内核态指的是操做系统的内核,是操做系统中包含重要系统功能的部分。

表3.7 操做系统内核的典型功能

 

使用两种模式的缘由:保护操做系统和重要的操做系统表(如进程控制块)不受用户程序的干涉。在内核态下,软件具备对处理器以及全部指令、寄存器和内存的控制能力,这一级的控制对用户程序不是必需的,且为了安全起见也不是用户程序可访问的。

这样产生了两个问题:处理器如何知道它正在什么模式下执行以及如何改变这一模式。
对第一个问题,程序状态字中有一位表示执行模式,这一位应某些事件的要求而改变。在典型状况下,当用户调用一个操做系统服务或中断触发系统例程的执行时,执行模式被设置成内核态,当从系统服务返回到用户进程时,执行模式被设置为用户态。例如64 位IA-64 体系结构的Intel Itanium 处理器,有一个处理器状态寄存器(PSR),包含2 位的CPL(当前特权级别)域,级别0 是最高特权级别,级别3 是最低特权级别。大多数操做系统,如Linux,使用级别0 做为内核态,使用另外一个级别做为用户态。当中断发生时,处理器清空大部分PSR 中的位,包括CPL域,这将自动把CPL 设置为0。在中断处理例程结束时,最后的一个指令是irt(中断返回),这条指令使处理器恢复中断程序的PSR 值,也就是恢复了程序的特权级别。当应用程序调用一个系统调用时,会发生相似的状况。对于Itanium,应用程序使用系统调用是经过如下方式实现的:把系统调用标识符和参数放在一个预约义的区域,而后经过执行一个特殊的指令中断用户态程序的执行,并把控制权交给内核。

3.4.2 进程建立

讨论了与进程相关的数据结构后,可简单描述实际建立进程时的步骤。

一旦操做系统决定基于某种缘由(见表3.1)建立一个新进程,可按如下步骤进行:

  • 给新进程分配一个惟一的进程标识符。此时,在主进程表中增长一个新表项,表中的每一个新表项对应着一个进程。
  • 进程分配空间。这包括进程映像中的全部元素。操做系统须知道私有用户地址空间(程序和数据)和用户栈须要多少空间。能够根据进程的类型使用默认值,也能够在做业建立时根据用户请求设置。若是一个进程是由另外一个进程生成的,则父进程能够把所需的值做为进程建立请求的一部分传递给操做系统。若是任何现有的地址空间被这个新进程共享,则必须创建正确的链接。最后,必须给进程控制块分配空间。
  • 初始化进程控制块。进程标识符部分;处理器状态信息部分的大多数项目一般初始化成0,除了程序计数器(被置为程序入口点)和系统栈指针(用来定义进程栈边界);进程控制信息部分的初始化基于标准默认值和为该进程所请求的属性。例如,进程状态在典型状况下被初始化成就绪或就绪/挂起;除非显式地请求更高的优先级,不然优先级的默认值为最低优先级;除非显式地请求或从父进程处继承,不然进程最初不拥有任何资源(I/O 设备、文件)。
  • 设置正确的链接。例如,若是操做系统把每一个调度队列都保存成链表,则新进程必须放置在就绪或就绪/挂起链表中。
  • 建立或扩充其余数据结构。例如,操做系统可能为每一个进程保存着一个记帐文件,可用于编制帐单和/或进行性能评估。

3.4.3 进程切换

表面看进程切换的功能是简单的。某一时刻,一个正在运行的进程被中断,操做系统指定另外一个进程为运行态,并把控制权交给这个进程。

  • 什么事件触发进程的切换?
  • 模式切换与进程切换之间的区别。
  • 为实现进程切换,操做系统须对它控制的各类数据结构作些什么?

什么时候切换进程

进程切换在操做系统从当前正在运行的进程中得到控制权的任什么时候刻发生。表3.8 给出了可能把控制权交给操做系统的事件。

1、系统中断。大多数操做系统区分两种类型的系统中断:

  • 中断,与当前正在运行的进程无关的某种类型的外部事件相关,如完成一次I/O 操做;
  • 陷阱,与当前正在运行的进程所产生的错误或异常条件相关,如非法的文件访问。

对于普通中断,控制首先转移给中断处理器,它作一些基本的辅助工做,而后转到与已经发生的特定类型的中断相关的操做系统例程。参见如下例子:

  • 时钟中断:操做系统肯定当前正在运行的进程的执行时间是否已经超过了最大容许时间段(时间片,即进程在被中断前能够执行的最大时间段),若是超过了,进程必须切换到就绪态,调入另外一个进程。
  • I/O 中断:操做系统肯定是否发生了I/O 活动。若是I/O 活动是一个或多个进程正在等待的事件,操做系统就把全部相应的阻塞态进程转换到就绪态(阻塞/挂起态进程转换到就绪/挂起态),操做系统必须决定是继续执行当前处于运行态的进程,仍是让具备高优先级的就绪态进程抢占这个进程。
  • 内存失效:处理器访问一个虚拟内存地址,且此地址单元不在内存中时,操做系统必须从外存中把包含这个引用的内存块(页或段)调入内存中。在发出调入内存块的I/O 请求以后,操做系统可能会执行一个进程切换,以恢复另外一个进程的执行,发生内存失效的进程被置为阻塞态,当想要的块调入内存中时,该进程被置为就绪态。

2、对于陷阱,操做系统肯定错误或异常条件是不是致命的。若是是,当前正在运行的进程被转换到退出态,并发生进程切换;若是不是,操做系统的动做取决于错误的种类和操做系统的设计,其行为能够是试图恢复或通知用户,操做系统可能会进行一次进程切换或者继续执行当前正在运行的进程。

3、操做系统可能被来自正在执行的程序的系统调用激活。例如,一个用户进程正在运行,而且正在执行一条请求I/O 操做的指令,如打开文件,这个调用致使转移到做为操做系统代码一部分的一个例程上执行。一般,使用系统调用会致使把用户进程置为阻塞态。

表3.8 进程执行的中断机制

 

模式切换

中断阶段,处理器经过中断信号检查是否发生了任何中断。若没有未处理的中断,处理器继续取指令周期,即取当前进程中的下一条指令,若存在未处理的中断,处理器须要作如下工做:

  • 把程序计数器置成中断处理程序的开始地址
  • 从用户态切换到内核态,使得中断处理代码能够包含有特权的指令

处理器继续取指阶段,并取中断处理程序的第一条指令,它将给中断提供服务。此时,被中断的进程上下文保存在被中断程序的进程控制块中

保存的上下文环境包括什么?全部中断处理可能改变的信息和恢复被中断程序时所须要的信息。所以,须保存称作处理器状态信息的进程控制块部分,这包括程序计数器、其余处理器寄存器和栈信息。

还须要作些其余工做吗?取决于下一步会发生什么。中断处理程序一般执行与中断相关的基本任务的小程序。例如,它重置表示出现中断的标志或指示器。可能给产生中断的实体如I/O 模块发送应答。它还作一些与产生中断的事件结果相关的基本辅助工做。例如,若是中断与I/O 事件有关,中断处理程序将检查错误条件;若是发生了错误,中断处理程序给最初请求I/O操做的进程发一个信号。若是是时钟中断,处理程序将控制移交给分派器,当分配给当前正在运行进程的时间片用尽时,分派器将控制转移给另外一个进程。

进程控制块中的其余信息如何处理?若是中断以后是切换到另外一个应用程序,则须要作一些工做。可是,在大多数操做系统中,中断的发生并非必须伴随着进程切换的。多是中断处理器执行以后,当前正在运行的进程继续执行。在这种状况下,所须要作的是当中断发生时保存处理器状态信息,当控制返回给这个程序时恢复这些信息。在典型状况下,保存和恢复功能由硬件实现。

进程状态的变化

显然,模式切换与进程切换是不一样的。发生模式切换能够不改变正处于运行态的进程状态,这种状况下,保存上下文环境和之后恢复上下文环境只须要不多的开销。可是,若是当前正在运行的进程被转换到另外一个状态(就绪、阻塞等),则操做系统必须使其环境产生实质性的变化,完整的进程切换步骤以下:

  • 保存处理器上下文环境,包括程序计数器和其余寄存器。
  • 更新当前处于运行态进程的进程控制块,包括将进程的状态改变到另外一状态(就绪态、阻塞态、就绪/挂起态或退出态)。还必须更新其余相关域,包括离开运行态的缘由和记帐信息。
  • 将进程的进程控制块移到相应的队列(就绪、在事件i 处阻塞、就绪/挂起)。
  • 选择另外一个进程执行,这方面的内容将在本书的第四部分探讨
  • 更新所选择进程的进程控制块,包括将进程的状态变为运行态。
  • 更新内存管理的数据结构,这取决于如何管理地址转换,这方面的内容将在第三部分探讨。
  • 恢复处理器在被选择的进程最近一次切换出运行状态时的上下文环境,这能够经过载入程序计数器和其余寄存器之前的值来实现。

所以,进程切换涉及状态变化,于是比模式切换须要作更多的工做。

3.5 操做系统的执行

操做系统的两个特殊事实:

  • 操做系统与普通的计算机软件以一样的方式运行,也就是说,它也是由处理器执行的一个程序。
  • 操做系统常常释放控制权,而且依赖于处理器恢复控制权。

若操做系统仅仅是一组程序,那么操做系统是一个进程吗?若是是,如何控制它?这些有趣的问题列出了大量的设计方法,图3.15 给出了在当代各类操做系统中使用的各类方法。

3.5.1 无进程的内核

老操做系统中,传统和通用的方法是在全部的进程以外执行操做系统内核(见图3.15a)。经过这种方法,在当前正运行的进程被中断或产生一个系统调用时,该进程的模式上下文环境被保存起来,控制权转交给内核。操做系统有本身的内存区域和系统栈,用于控制过程调用和返回。操做系统能够执行任何预期的功能,并恢复被中断进程的上下文,这将致使被中断的用户进程从新继续执行。或者,操做系统能够完成保存进程环境的功能,并继续调度和分派另外一个进程,是否这样作取决于中断的缘由和当前的状况。

不管哪一种状况,其关键点是进程的概念仅仅适用于用户程序,操做系统代码做为一个在特权模式下工做的独立实体被执行。

3.5.2 在用户进程中执行

在较小的机器的操做系统中,常见的方法是在用户进程的上下文中执行几乎全部操做系统软件。其观点是操做系统从根本上说是用户调用的一组例程,在用户进程环境中执行,用于实现各类功能,如图3.15b 所示。在任什么时候刻,操做系统管理着n 个进程映像,每一个映像不只包括图3.13 中列出的区域,并且还包括内核程序的程序、数据和栈区域。

 
图3.15 操做系统和用户进程的关系

图3.16 给出了这个策略下的一个典型的进程映像结构。当进程在内核态下时,独立的内核栈用于管理调用/返回。操做系统代码和数据位于共享地址空间中,被全部的用户进程共享。

 
图3.16 进程映像:操做
系统在用户空间中执行

当发生一个中断、陷阱或系统调用时,处理器被置于内核态,控制权转交给操做系统。为了将控制从用户程序转交给操做系统,须要保存模式上下文环境并进行模式切换,而后切换到一个操做系统例程,但此时仍然是在当前用户进程中继续执行,所以,不须要执行进程切换,仅在同一个进程中进行模式切换。

若是操做系统完成其操做后,肯定须要继续运行当前进程,则进行一次模式切换,在当前进程中恢复被中断的程序。该方法的重要优势之一是,一个用户程序被中断以使用某些操做系统例程,而后被恢复,全部这些不用以牺牲两次进程切换为代价。若是肯定须要发生进程切换而不是返回到先前执行的程序,则控制权被转交给进程切换例程,这个例程可能在当前进程中执行,也可能不在当前进程中执行,这取决于系统的设计。在某些特殊的状况下,如当前进程必须置于非运行态,而另外一个进程将指定为正在运行的进程。为方便起见,这样一个转换过程在逻辑上能够看作是在全部进程以外的环境中被执行的。

在某种程度上,对操做系统的这种见解是很是值得注意的。在某些时候,一个进程能够保存它的状态信息,从就绪态进程中选择另外一个进程,并把控制权释放给这个进程。之因此说这是一种混杂的状况,是由于在关键时候,在用户进程中执行的代码是共享的操做系统代码而不是用户代码。基于用户态和内核态的概念,即便操做系统例程在用户进程环境中执行,用户也不能篡改或干涉操做系统例程。这进一步说明进程和程序的概念是不一样的,它们之间不是一对一的关系。在一个进程中,用户程序和操做系统程序都有可能执行,而在不一样用户进程中执行的操做系统程序是相同的。

3.5.3 基于进程的操做系统

图3.15c 中显示的是另外一种选择,即把操做系统做为一组系统进程来实现。与其余选择同样,做为内核一部分的软件在内核态下执行。不过在这种状况下,主要的内核函数被组织成独立的进程,一样,还可能有一些在任何进程以外执行的进程切换代码。

这种方法有几个优势。它利用程序设计原理,促使使用模块化操做系统,而且模块间具备最小的、简明的接口。此外,一些非关键的操做系统函数可简单地用独立的进程实现,例如,很早就曾经提到过的用于记录各类资源(处理器、内存、通道)的使用程度和系统中用户进程的执行速度的监控程序。因为这个程序没有为任何活动进程提供特定的服务,它只能被操做系统调用。做为一个进程,这个函数能够在指定的优先级上运行,而且在分派器的控制下与其余进程交替执行。最后,把操做系统做为一组进程实现,在多处理器或多机环境中都是十分有用的,这时一些操做系统服务能够传送到专用处理器中执行,以提升性能。

3.6 安全问题

操做系统对于每一个进程都关联了一套权限。这些权限规定了进程能够获取哪些资源,包括内存区域、文件和特权系统指令等。典型的是,一个进程的运行表明着一个用户拥有操做系统认证的权限。在配置的时候,一个系统或者是一个实用进程就被分配了权限。

在一个典型的系统中,最高级别的权限指的是管理员、超级用户或根用户的访问权限。根用户的访问权限提供了对一个操做系统全部的功能和服务的访问。一个有着根用户访问权限的进程能够安全地控制一个系统,能够增长或者改变程序和文件,对其余进程进行监控,发送和接收网络流量和改变权限。

设计任何操做系统的一个关键问题是阻止或者至少是探测一个用户或者是一种恶意软件(恶意程序)得到系统受权的权限的企图,尤为是从根用户获取。本节,咱们将简短地总结关于这种安全问题的威胁和对策。在第七部分将对其作更加详细的阐述。

3.6.1 系统访问威胁

系统访问威胁分为两大类:入侵者和恶意软件。

入侵者

对于安全,一个最普通的威胁就是入侵者(另一个是病毒),一般是指黑客和解密高手。在早期的一项对入侵的重要研究中,Anderson [ANDE80] 定义了三种类型的入侵者:

冒充者:没有受权的我的去使用计算机和经过穿透系统的访问控制去使用一个合法用户的帐号。

滥用职权者:一个合法的用户访问没有受权的数据、程序或资源,或者用户具备这种访问的受权,可是滥用了他的权限。

秘密用户:一个用户得到了系统的管理控制,而后使用这种控制来逃避审计和访问控制,或者废止审查收集。

冒充者有可能就是外部人员;滥用职权者通常都是内部人员;秘密用户多是外部人员也多是内部人员。

入侵者的攻击有良性的也有严重的。在良性阶段,许多人仅仅是想浏览互联网并想知道在互联网上到底有什么。在严重阶段,这些人尝试着去读权限数据,修改未受权的数据或者是破坏系统。

入侵者的目的是得到一个系统的访问权限,或是增长一个系统的权限获取的范围。最初许多攻击是利用了系统或软件的漏洞,这些漏洞可让用户执行能够开启系统后门的代码。当程序以必定的权限运行,入侵者能够利用如缓冲溢出区攻击来得到系统的访问。将在7 章介绍缓冲区溢出攻击。

此外,入侵者也能够尝试获取那些已经被保护的信息。在一些状况下,信息就是在表框里面的用户密码。若是知道了一些用户的密码,那么入侵者能够登陆一个系统,而后运行合法用户的全部权限。

恶意软件

计算机系统最为复杂的威胁可能就是利用计算机系统漏洞的程序。这些威胁被称为恶意软件,或者是恶意程序。在这一部分,咱们将关注如编辑器、编译器和内核级程序等应用程序以及通用程序的威胁。

恶意软件分为两大类:一种须要宿主程序,一种则是独立的。对于前者,也被称为寄生,其本质上是一些不能独立于实际应用程序、通用程序或系统程序而存在的片断,例如病毒、逻辑炸弹和后门。后者则是独立并能够被操做系统调度和运行的程序,例如蠕虫和僵尸程序。

咱们也能够对这些软件威胁进行如下的区分:一种不能进行复制,而另一种则能够。前者是经过触发器激活的程序或者程序片断,例如,逻辑炸弹、后门和僵尸程序。后者由一个程序片断或者一个独立的程序构成,当其运行后,可能产生一个或者多个它本身的副本,这些副本将在同一系统或其余系统中被激活,例如病毒和蠕虫。

比较而言,恶意软件多是无害的,或者表现为一个或多个有害的操做,这些有害的操做包括毁坏内存里的文件和数据,经过绕开控制而得到权限访问和为入侵者提供一种绕开访问控制的方法。

3.6.2 对抗措施

入侵检测

RFC2828(网络安全术语表)对入侵检测的定义以下:入侵检测是一种安全服务,经过监控和分析系统事件发现试图经过未经受权的方法访问系统资源的操做,并对这种操做提供实时或者准实时的警告。

入侵检测系统(IDS)能够分为以下几类:

基于宿主的IDS:对于可疑活动,监控单个宿主的特征和发生在宿主上的事件。

基于网络的IDS:监控特定的网络段或者设备网络流量,分析网络、传输和应用协议来辨别可疑活动。

IDS 由三个部分组成:

感应器:感应器负责收集数据。感应器的输入多是系统的任一部分,输入可能包含了侵扰的证据。典型的感应器输入包括网络包、日志文件和系统调用记录。感应器收集这些信息,并把这些信息发送给分析器。

分析器:分析器从一个或多个感应器或者其余分析器接受输入数据。分析器负责肯定入侵是否发生。这部分的输出代表了一个入侵已经发生。输出可能包含了支持入侵发生的结论的证据。分析器可能提供对于入侵结果采起何种操做的指导。

用户界面:IDS 的用户界面可让用户查看系统的输出和控制系统的行为。在一些系统中,用户界面能够等同于负责人、控制器或者控制台部分。

入侵检测系统用来侦测人类入侵者行为,以及恶意软件的行为。

认证

在许多计算机安全内容中,用户认证是一个主要的构建模块和最初防线。用户认证是许多种访问控制和用户责任的主要部分。RFC2828 对用户认证作了以下定义:

系统实体定义了验证和确认的过程。认证过程包括如下两步:

确认步骤:对于安全系统,提出了标识符。(应当心地分配标识符,对于访问控制服务等其余安全服务,认证定义是基本部分。)

验证步骤:提出或产生认证信息,用来证明在实体与标识符之间的绑定。

例如,用户Alice Toklas 拥有一个用户标识符ABTOKLAS。标识符信息可能被存储在Alice想要使用的任意一台服务器或者计算机系统中,并且系统管理员和其余用户可能知道这些信息。一种典型的与用户ID 相关联的认证信息项就是密码,密码是用于保守秘密的(秘密仅仅被Alice和系统所知)。若是没有人获得或猜出Alice 的密码,管理员能够经过Alice 的用户ID 和密码的结合创建Alice 的访问许可,并审核Alice 的操做。因为Alice 的ID 不是秘密,系统用户能够给她发送电子邮件,可是因为她的密码是保密的,因此没有人能够冒充成Alice。

本质上,识别是这样一种方法:用户向系统提供一个声明的身份;用户认证就是确认声明的合法性的方法。

一共有4 种主要的认证用户身份的方法,它们既能够单独使用,也能够联合使用:

我的知道的一些事物:例如包括密码、我的身份号码(PIN)或者是预先安排的一套问题的答案。

我的拥有的一些事物:例如包括电子通行卡、智能卡、物理钥匙。这种类型的身份验证称为令牌。

我的自身的事物(静态生物识别技术):例如包括指纹、虹膜和人脸的识别。

我的要作的事物(动态生物识别技术):例如包括语音模式、笔迹特征和输入节奏的识别。

适当的实现和使用全部的这些方法,能够提供可靠的用户认证。可是每一个方法都有问题,使得对手可以猜想或盗取密码。相似地,用户可以伪造或盗取令牌。用户可能忘记密码或丢失令牌。并且,对于管理系统上的密码、令牌信息和保护系统上的这些信息,还存在显著的管理开销。对于生物识别技术,也有各类各样的问题,包括误报和假否认、用户接受程度、费用和便利与否。

访问控制

访问控制实现了一种安全策略:指定谁或何物(例如进程的状况)可能有权使用特定的系统资源和在每一个场景下被容许的访问类型。

访问控制机制调节了用户(或是表明用户执行的进程)与系统资源之间的关系,系统资源包括应用程序、操做系统、防火墙、路由器、文件和数据库。系统首先要对寻求访问的用户进行认证。一般,认证功能彻底决定了用户是否被容许访问系统。而后访问控制功能决定了是否容许用户的特定访问要求。安全管理员维护着一个受权数据库,对于容许用户对何种资源采用什么样的访问方式,受权数据库作了详细说明。访问控制功能参考这个数据库来决定是否准予访问。审核功能监控和记录了用户对于系统资源的访问。

防火墙

对于保护本地系统或系统网络免于基于网络的安全威胁,防火墙是一种有效的手段,而且防火墙同时提供了通过广域网和互联网对外部网络的访问。传统上,防火墙是一种专用计算机,是计算机与外部网络的接口;防火墙内部创建了特殊的安全预防措施用以保护网络中计算机上的敏感文件。其被用于服务外部网络,尤为是互联网、链接和拨号线路。使用硬件或软件来实现,而且与单一的工做站或者PC 链接的我的防火墙也很常见。

[BELL94]列举了以下防火墙的设计目标:

1)从内部到外部的通讯必须经过防火墙,反之亦然。经过对除通过防火墙以外本地网络的全部访问都进行物理阻塞来达到目的。能够对其进行各类各样的配置,将在本章的后面部分进行阐述。

2)仅仅容许本地安全策略定义的受权通讯经过。使用的不一样类型防火墙是经过不一样类型的安全策略实现的。

3)防火墙自己对于渗透是免疫的。这意味着在一个安全的操做系统上使用强固系统。值得信赖的计算机系统适合用做防火墙,而且在管理应用中也被要求使用。

3.7 UNIX SVR4 进程管理

UNIX 系统V 使用了一种简单可是功能强大的进程机制,且对用户可见。UNIX 采用图3.15b 中的模型,其中大部分操做系统在用户进程环境中执行。UNIX 使用两类进程,即系统进程和用户进程。系统进程在内核态下运行,执行操做系统代码以实现管理功能和内部处理,如内存空间的分配和进程交换;用户进程在用户态下运行以执行用户程序和实用程序,在内核态下运行以执行属于内核的指令。当产生异常(错误)或发生中断或用户进程发出系统调用时,用户进程可进入内核态。

3.7.1 进程状态

UNIX 操做系统中共有9 种进程状态,如表3.9 所示。图3.17(基于[BACH86]中的图)是相应的状态转换图,它与图3.9b 相似,有两个UNIX 睡眠状态对应于图3.9b 中的两个阻塞状态,其区别可简单归纳以下:

UNIX 采用两个运行态表示进程在用户态下执行仍是在内核态下执行。

UNIX 区份内存中就绪态和被抢占态这两个状态。从本质上看,它们是同一个状态,如图中它们之间的虚线所示,之因此区分这两个状态是为了强调进入被抢占状态的方式。当一个进程正在内核态下运行时(系统调用、时钟中断或I/O 中断的结果),内核已经完成了其任务并准备把控制权返回给用户程序时,就可能会出现抢占的时机。这时,内核可能决定抢占当前进程,支持另外一个已经就绪并具备较高优先级的进程。在这种状况下,当前进程转换到被抢占态,可是为了分派处理,处于被抢占态的进程和处于内存中就绪态的进程构成了一条队列。

 
图3.17 UNIX 进程状态转换图

只有当进程准备从内核态移到用户态时才可能发生抢占,进程在内核态下运行时是不会被抢占的,这使得UNIX 不适用于实时处理。有关实时处理需求的讨论请参见第10 章。

UNIX 中有两个独特的进程。进程0 是一个特殊的进程,是在系统启动时建立的。实际上,这是预约义的一个数据结构,在启动时刻被加载,是交换进程。此外,进程0 产生进程1,称作初始进程,进程1 是系统中的全部其余进程的祖先。当新的交互用户登陆到系统时,由进程1为该用户建立一个用户进程。随后,用户进程能够建立子进程,从而构成一棵分支树,所以,任何应用程序都是由一组相关进程组成的。

表3.9 UNIX 进程状态

 

 

3.7.2 进程描述

UNIX 中的进程是一组至关复杂的数据结构,它给操做系统提供管理进程和分派进程所须要的全部信息。表3.10 归纳了进程映像中的元素,它们被组织成三部分:用户上下文、寄存器上下文和系统级上下文。

表3.10 UNIX 进程映像

 

 

 

用户级上下文包括用户程序的基本成分,能够由已编译的目标文件直接产生。用户程序被分红正文和数据两个区域,正文区是只读的,用于保存程序指令。当进程正在执行时,处理器使用用户栈进行过程调用和返回以及参数传递。共享内存区是与其余进程共享的数据区域,它只有一个物理副本,可是经过使用虚拟内存,对每一个共享进程来讲,共享内存区看上去好像在它们各自的地址空间中同样。当进程没有运行时,处理器状态信息保存在寄存器上下文中。

系统级上下文包含操做系统管理进程所须要的其他信息,它由静态部分和动态部分组成,静态部分的大小是固定的,贯穿于进程的生命周期;动态部分在进程的生命周期中大小可变。静态部分的一个成分是进程表项,这其实是由操做系统维护的进程表的一部分,每一个进程对应于表中的一项。进程表项包含对内核来讲老是能够访问到的进程控制信息。所以,在虚拟内存系统中,全部的进程表项都在内存中,表3.11 中列出了进程表项的内容。用户区,即U 区,包含内核在进程的上下文环境中执行时所须要的额外的进程控制信息,当进程调入或调出内存时也会用到它。表3.12 给出了这个表的内容。

表3.11 UNIX 进程表项

 

 

 

(续)

 

 

 


表3.12 UNIX 的U 区

 

 

 

进程表项和U 区的区别反映出UNIX 内核老是在某些进程的上下文环境中执行,大多数时候,内核都在处理与该进程相关的部分,可是,某些时候,如当内核正在执行一个调度算法,准备分派另外一个进程时,它须要访问其余进程的相关信息。当给定进程不是当前进程时,能够访问进程控制表中的信息。

系统级上下文静态部分的第三项是本进程区表,它由内存管理系统使用。最后,内核栈是系统级上下文环境的动态部分,当进程正在内核态下执行时须要使用这个栈,它包含当发生过程调用或中断时必须保存和恢复的信息。

3.7.3 进程控制

UNIX 中的进程建立是经过内核系统调用fork()实现的。当一个进程产生一个fork 请求时,操做系统执行如下功能[BACH86]:

1)为新进程在进程表中分配一个空项。

2)为子进程赋一个惟一的进程标识符。

3)作一个父进程上下文的逻辑副本,不包括共享内存区。

4)增长父进程拥有的全部文件的计数器,以表示有一个另外的进程如今也拥有这些文件。

5)把子进程置为就绪态。

6)向父进程返回子进程的进程号;对子进程返回零。

全部这些操做都在父进程的内核态下完成。为当内核完成这些功能后能够继续下面三种操做之一,它们能够认为是分派器例程的一个部分:

在父进程中继续执行。控制返回用户态下父进程进行fork 调用处。

处理器控制权交给子进程。子进程开始执行代码,执行点与父进程相同,也就是说在fork调用的返回处。

控制转交给另外一个进程。父进程和子进程都置于就绪状态。

很难想象这种建立进程的方法中父进程和子进程都执行相同的代码。其区别在于:当从fork中返回时,测试返回参数,若是值为零,则它是子进程,能够转移到相应的用户程序中继续执行;若是值不为零,则它是父进程,继续执行主程序。

3.8 小结

现代操做系统中最基本的构件是进程,操做系统的基本功能是建立、管理和终止进程。当进程处于活跃状态时,操做系统必须设法使每一个进程都分配处处理器执行时间,并协调它们的活动、管理有冲突的请求、给进程分配系统资源。

为执行进程管理功能,操做系统维护着对每一个进程的描述,或者称为进程映像,它包括执行进程的地址空间和一个进程控制块。进程控制块含有操做系统管理进程所须要的全部信息,包括它的当前状态、分配给它的资源、优先级和其余相关数据。

在整个生命周期中,进程老是在一些状态之间转换。最重要的状态有就绪态、运行态和阻塞态。一个就绪态进程是指当前没有执行但已作好了执行准备的进程,只要操做系统调度到它就当即能够执行;运行态进程是指当前正在被处理器执行的进程,在多处理器系统中,会有多个进程处于这种状态;阻塞态进程正在等待某一事件的完成,如一次I/O 操做。

一个正在运行的进程可被一个在进程外发生且被处理器识别的中断事件打断,或者被执行操做系统的系统调用打断。不论哪一种状况,处理器都执行一次模式切换,把控制转交给操做系统例程。操做系统在完成必需的操做后,能够恢复被中断的进程或者切换到别的进程。

相关文章
相关标签/搜索