首页 > 代码库 > 【操作系统】线程

【操作系统】线程

进程用于把资源集中到一起,也就是资源管理的单位,而线程则是在CPU上被调度执行的实体。线程概念试图实现的是,共享一组资源的多个线程的执行能力,以便这些线程可以为完成某一任务而共同工作。在有了多进程的情况下,还需要多线程的原因有以下几点:
  1. 同一进程中的多个线程运行在相同的地址空间并共享所有可用数据,而进程则在互不相同的地址空间中。
  2. 线程比进程更轻量级,创建和撤销也更快。
  3. 使得多个不同操作的线程可以重叠进行。例如一个线程占用CPU,另一个处理I/O。
  4. 使得在多CPU环境下,真正的并行成为可能。

使用多线程的一个典型的例子是Web服务器。
一个服务器进程分为多个线程:一个分派线程和多个工作线程。当客户端的请求到达时,分配线程选择一个工作线程对处理进行相应。工作线程从Web页面高速缓存直接返回响应或从磁盘调取Web页面(I/O操作)。在这个过程中,分派线程是可以继续接受来自客户端的请求并选择另一个工作线程进行响应的,工作线程进行的耗时的I/O操作并没有影响整个服务器的性能。这个例子使用多线程不仅因为其并行性,而且其Web页面高速缓存是被这些线程所共享的,而多个进程是无法实现这样的共享的。如果一个程序需要进行:读—处理—写这三个步骤时,使用多线程分别完成三个阶段的工作是很有优势的。

线程模型
由于线程具有进程的某些性质,所有有时被称为轻量级进程。多进程和多线程的形象表示如下图所示:


a中的三个进程运行在不同的地址空间,而b中的三个线程则运行在相同的地址空间。对多进程和多线程的选择往往要根据实际情况。当三个任务不需要任何关联的时候,选择a中的多线程;当三个任务之间相互协作、关系密切时,则使用b中的多线程。

每个线程都有自己的堆栈。因为每个线程都有一系列的函数调用,这些调用所要保存的信息应该是彼此分离地存放在每个线程对应的堆栈中的。这使得不同的线程有各自不同的执行历史,如下图所示:


用户空间线程
整个线程都在在用户空间中运行,内核对线程包一无所知,内核只是将它视为单线程进程。这些线程由运行时系统管理,运行时系统是一个管理线程的函数集合,例如:pthread_create等函数接口。一个进程中包含一个线程表,用于跟踪本进程内的线程状态,线程表由运行时系统管理。线程间的调度是通过运行时系统来管理的,运行时系统总是选择自己进程中的线程进行切换。用户空间线程如下图所示:


内核空间线程
在内核空间的线程不再需要运行时系统,每个进程中也无需线程表,一个记录系统中所有线程的线程表放在内核中。线程的创建或销毁都是通过系统调用并修改线程表来完成的。线程间的调度由内核来负责,不同于运行时系统,内核会在所有线程范围内选择下一个运行的线程,而不只是局限于某一个进程。线程的每一次阻塞都要通过系统调用陷入内核才能完成,从而增大了内核空间线程的开销。内核空间线程如下图所示:


参考:
《现代操作系统》 P53-P62.