早期的操作系统(例如单道批处理系统),一次只能处理一个任务(或者称一个程序),每个处于执行状态的任务(程序)都可以占用计算机中大部分甚至全部的可用资源。
随着计算机硬件和软件的快速发展,操作系统也在不断蜕变。举个例子,操作系统开始支持将多个任务一次性读取到内存中并同时执行它们,例如多道批处理系统、分时操作系统等。通常,我们将具备这种功能的操作系统称为多任务操作系统。
相对地,我们通常将“同时仅能执行一个任务”的系统称为单任务操作系统。
显然和单任务操作系统相比,多任务操作系统需要严格地控制和管理各个任务的执行流程以及计算机资源的分配与回收,因此引入了“进程”这个概念。
进程是什么
进程的概念最早出现在 20 世纪 60 年代,简单地理解,一个处于执行状态的程序就是一个进程。
再次强调,“运行”的程序才可以称为进程。未运行的程序仅仅是一些指令和数据的集合,并非进程。
多任务操作系统可能同时存在多个进程,操作系统负责为每个创建的进程分配所需要的计算机资源,同时负责在进程退出时将资源回收。此外,各个进程的执行顺序也由操作系统决定。
当一个程序被载入内存并成为一个进程后,它会占用一部分存储空间,此空间会分为 4 个区域,如图 1 所示:
图 1 一个进程的内部结构
这 4 个区域的作用分别是:
- 栈(Stack):存储局部变量、函数参数等临时数据。
- 堆(Heap):进程执行期间可以动态申请这部分空间。
- 数据区(Data):存储全局变量和静态变量。
- 文本区(Text):存储进程要执行的机器指令代码。
进程的状态
早期的单任务操作系统中,每个任务都会一直占用着 CPU 资源,直到执行结束。而多任务操作系统中,系统会权衡各个进程占用 CPU 的时间,必要时会强制将 CPU 资源转交给另一个进程使用,从而提高 CPU 资源的利用率。
多任务操作系统中,进程在执行过程中可能会经历多种状态(如图 2 所示)。
图 2 进程的各种状态
这 5 种状态的含义分别是:
- 开始状态:所有创建好的进程的初始状态。
- 就绪状态:处于该状态的进程,正在等待操作系统分配 CPU 资源。位于“开始”状态并已创建好的进程会直接进入此状态,位于“运行”或者“等待”状态的进程也可能会重新进入此状态。
- 运行状态:操作系统会挑选“就绪”状态的某个进程并将 CPU 分配给它,该进程的状态会随即转为运行状态。同一时间处于运行状态的进程只能有 1 个。
- 等待状态:如果处于“运行状态”的进程需要等待某些资源(例如等待用户输入测试数据),则它将由运行状态转为等待状态。
- 终止状态:一旦进程执行完毕,或者被操作系统终止执行,它的状态将变成终止状态。该状态下的进程会被操作系统从内存中删除。
注意,以上列举了进程可能历经的所有状态,但并非每一个进程都会经历以上所有的状态。例如,有些进程的执行过程可能只经历了“开始 -> 就绪 -> 运行 -> 终止”这 4 种状态,并未进入“等待”状态。