9.3.2 进程与线程

操作系统控制处理器在多个程序之间切换执行的过程称为调度。传统的多任务操作系统是以进程为单位进行调度的。进程(process)是指程序的一次执行所形成的实体,每当程序 开始执行,就会创建一个进程。每个进程由程序代码以及一些状态信息(如进程数据的当前 值和当前执行点等)组成,状态信息也称为进程的上下文。

注意,程序与进程是不同的概念。首先,不同程序在计算机中执行,自然形成不同的进 程。其次,即使是同一个程序,当它在计算机中多次执行时,也会创建多个不同进程,这些 进程虽然具有相同的程序代码,但各有自己的上下文。例如,在 Windows 中我们可以同时 运行多个记事本程序(notepad.exe),以便编辑多个文本文件。这时,在系统中就创建了多 个 notepad 进程①。

通常,操作系统通过划分时间片来调度进程,各进程分时占有处理器来执行指令。从宏 观上看,多个进程是在同时运行。这就是操作系统的多任务机制。如前所述,多进程并发执 行可以提高系统资源的利用率。

但是,多任务、多进程也有缺点。第一,实现多进程并发需要花费不少系统开销。因为 每创建一个进程都要为它分配一些内存,以便存储它的上下文;而操作系统在不同进程间进 行调度时需要保存和恢复进程上下文。第二,进程间通信比较困难。进程和进程是隔离的, 各进程拥有自己的地址空间,一个进程不能访问另一个进程的地址空间,从而在进程之间很 难共享信息。因此,对于两个需要传递信息的进程,相互通信很麻烦。

① Windows 用户可以通过任务管理器来查看所有已创建的进程。

为了解决上述两个问题,产生了线程的概念。传统程序是从第一行指令一直执行到最后 一行指令,程序中只有一个控制流。这就像写小说时,沿着唯一的故事线索推进。而所谓线程(thread),是指程序中的一段代码,它构成程序中一个相对独立的执行单位。线程概念 使我们可以从一个程序中分出多个控制流来执行多个任务,所以线程实际上是程序内部的多 任务机制。就好比一部小说在叙述过程中,同时存在着多个故事线索,多头并进。图 9.1 给 出了单线程与多线程的示意图。

图 9.1 单线程程序与多线程程序

线程的字面意义就是程序(在执行时就是进程)的一个执行“线索”,一个程序中可以

有多个执行线索。《三国演义》里讲到庞统处理公务的故事,他“手中批判,口中发落,耳 内听词”,不到半天就把积攒了一百多天的事情都处理掉了。用本节术语来说,庞统就是采 用了多线程并发执行技术,所以能够高效率地解决问题。

线程与进程既相似,也有明显的区别。系统中的多个进程一般是由执行不同程序而创建 的,而多个线程是同一程序(进程)的多个执行流;多个进程的状态是各自独立的,而多线 程可以共享地址空间(代码和上下文);调度进程时上下文切换比多线程的上下文切换开销 大;进程间通信比较麻烦,而线程之间通过共享内存很容易通信。

在单个处理器上,可通过分时抢占或者线程自身执行情况来实现多线程的并发执行。前 者由操作系统进行调度,后者由线程自己放弃控制(比如执行到一个休眠指令时)。不同线 程之间切换得非常快,因此在用户看来各线程是在同时执行的。可见多线程与多任务、多进 程机制的实现技术是类似的。

在多处理器或多核处理器系统中,各处理器或内核都可以执行线程,从而多线程可以真 正地并行执行。由于多核处理器现已成为主流,因此了解并利用多线程技术对程序设计来说 变得越来越重要。