在前文中,我们知道大多数操作系统都能够为底层硬件提供抽象的作用,作为中间人进行上层应用软件与下层硬件资源的管理,以及对下层硬件进行接口层面抽象以帮助上层应用软件的调用。
在上下的资源和信息的交互中,操作系统的必须要提供一种从抽象到具体的实际概念用来帮助建立更好的通信和交流。所以这篇文章也就是从操作系统的一些基本概念出发,介绍操作系统是如何在硬件与应用软件中建立起准确的通信桥梁。
1 进程
进程与程序
操作系统之中最为通用的概念就是「进程」。与此相关的面试题以及各种技术优化策略也层出不穷,足以够证明它对于理解操作系统中举足轻重的地位。事实上,通过「进程」,程序员可以更为直观的理解自己所开发的软件,并且能够从中深刻的认识到操作系统在软件运行做了些什么。
简单来讲,进程就是正在执行的程序。每个进程都包含有属于自己的一段地址空间,可以看作是一部分内存空间。在这样的地址空间中,进程能够根据需要进行内存的读写。
地址空间里面一般包含可执行程序,以及对应程序的数据及其堆栈。与每个进程相关的还有一组资源,通常包括寄存器(包括程序计数器和堆栈指针)以及运行程序所需的所有其他信息。从这可以看出,程序本身只是指令、数据以及其组织形式的一种描述方式,而程序的实际的运行实例就是一个进程。
不过进程与程序也并不完全等同,他们不是简单的一一对应的关系,而是在不同层面的表现形式。他们的主要区别在于:
- 程序是进程的静态文本,而进程是执行程序的动态过程;
- 进程与程序不是一一对应,同一程序可在不同进程中运行,一个进程也可以执行多个程序;
- 程序是一种长期可保存的文本,进程是暂时的一次执行过程;
- 进程是操作系统分配调度的独立单位,而程序是操作系统层级之上的应用程序。
进程状态
从上面我们知道,进程可看作是程序运行的动态过程。那么为了更好的对进程进行描述,我们给运行中的进程定义了三种基本状态,包括就绪、执行和阻塞。
这就是所谓的三态模型,描述了进程在整个运行周期中状态变化。每个状态的转移过程可以通过下图来表示。
就绪状态是指进程已经被分配到了所有必需的资源,除了CPU。在这个状态下,进程处于箭在弦上随时代发的状态,只要一获得CPU的执行权限,进程便会立刻执行,从而进入执行状态。
当有多个处于就绪状态的进程时,不同的进程会根据优先级被划分入不同的队列。一个因为时间片用完而进入就绪状态的进程会被划分入低优先级队列,而因为I/O操作完成而进入就绪状态的进程,则会被划分入高优先级队列。
执行状态是指进程正常运行的状态。而当处于执行状态的进程由于需要等待某个事件发送(通常为等待I/O)时,就会放弃CPU,从而进入暂时的阻塞状态。CPU这时一旦空出,通过不同的调度算法,CPU又会被分配给另一个就绪进程。
阻塞状态相当于就绪状态和执行状态的一个缓冲状态。当处于执行状态的进程无法正常执行时,会先进入阻塞状态,等待需要的请求执行完成,再回到就绪状态,等待下一次的CPU分配和执行。