操作系统原理及安全
第二章 进程与线程
“原理 机制 算法”
1 线程的概念
一些较受认可的定义:
- 线程 是进程的一个执行单元。
- 线程 是进程内的一个可调度实体。
- 线程 是程序(或进程)中相对独立的一个控制流序列。
- 线程 是执行的上下文,是是执行的现场数据和其他调度所需的信息。(这种观点来自Linux系统)
线程是CPU使用的基本单位。它由线程ID、程序计数器、寄存器集合和栈组成。它与属于同一进程的其他线程共享代码段、数据段和其他操作系统资源。
线程是进程内一个相对独立的、可调度的执行单元。线程自己基本上不拥有资源:只拥有一点在运行时必不可少的资源(如程序计数器、一组寄存器和栈),但它可以与同属一个进程的其他线程共享进程拥有的全部资源。
直接列出的这些定义不易理解且各个定义描述的角度与强调的重点也有差异。上面的表述中只说明了线程拥有哪些资源,对进程与线程关系的描述可能还是有些模糊抽象。下面对线程与进程进行一些比较,从而帮助我们更深入地理解进程与线程的联系与区别。
- 拥有资源上:
- 进程:由一个或多个线程及相关资源构成。更具体地,执行时的进程是由数据区、代码区、控制块(包含堆、栈指针)。
- 线程:一个进程中的多个线程共享所属进程的数据区、代码区与堆。每个线程拥有自己的栈区、一些资源(程序计数器、寄存器)。一个线程的堆栈指针、程序计数器和寄存器也可以称为线程的上下文。
- 调度上:
- 进程是拥有资源的基本单位,不同进程之间是相互隔离的。线程是调度的基本单位。
- 系统开销上:
- 进程的创建、撤销及切换均涉及资源管理,开销大。(涉及的操作和信息更多。)
- 线程创建涉及较少的资源管理;线程间的同步与通信开销小;线程切换的开销较进程切换的开销小。
推荐阅读:
进程与线程,你真的理解了吗?
文中很形象地讲解了关于进程与线程的联系与区别。
知乎上的一篇高赞回答
这篇回答中这个观点很impressive:“进程和线程都是一个时间段的描述,是CPU工作时间段的描述。是运行中的程序指令的一种描述,这需要与程序中的代码区别开来。”
一篇来自CSDN百家号的文章
(很奇怪的组合)对于进程各区的讲解值得阅读。
2 多线程
2.1 多线程的含义
多线程是指一个进程中有多个线程,这些线程共享该进程的状态和资源,它们在同一地址空间,并且可以访问到相同的数据。
2.2 多线程的优势
1.响应度好:如果进程部分阻塞,可以允许这个程序继续执行,如多线程浏览Web时候,一个线程装载图片可以利用另外一个线程接受用户交互。
(一个车间里的工人负责不同的任务,但这需要合理地把工作(大于“任务”)分成若干相对独立的任务。这样的机制优于“一个工人既做这个任务,又做那个任务”。如果是只有一个工人,那这个工人在一个任务上停住了,那整个工作就停滞了。)
2.开销小:线程的创建、撤销、切换开销更小。
3.资源共享:线程间的通信更方便,因为它们有共享的数据空间。
4.能更好地利用多核体系结构优势,可支持并行。
2.3 多线程模型
- 操作系统中有多种方式实现对线程的支持:
- 内核级线程
- 用户级线程
- 两种组合
2.3.1 内核级线程
- 内核级线程是指依赖于内核,由操作系统内核完成创建和撤消工作的线程。
- 在支持内核级线程的OS中,内核维护进程和线程的上下文信息并完成线程切换。
- 一个内核级线程阻塞时不会影响同一进程的其他线程的运行。
- 处理机时间分配对象是线程,所以有多个线程的进程将获得更多处理机时间。
2.3.2 用户级线程
-
用户级线程是指不依赖于操作系统核心,由应用进程利用用户级线程库提供创建、同步、调度和管理线程的函数来控制的线程。
-
用户级线程的维护由应用进程完成,可以用于不支持内核级线程的操作系统。用户级线程对OS不可见,OS调度的依然是进程。
-
在调度时,由线程库来切换TCB, PC, regs, stack
- 均是过程调用来实现,不涉及模式切换。(内核级线程的调度涉及模式切换,因此过细粒度的内核级线程并发会导致频繁的模式切换,从而带来性能的下降。)
-
优势:速度快100x
-
限制:
- **当一个线程阻塞时,整个进程都必须等待。**因为该进程的所有线程对内核来说都是一个调度实体,内核不知道这个进程有哪些线程,无法将其他线程调度到处理器上。这与内核级线程是不同的。
- 处理机时间分配对象是进程,每个用户级线程的执行时间相对少一些。
2.3.3 组合使用
在这种系统中,内核支持多线程的建立、调度与管理;同时,系统中又提供使用线程库的便利,允许用户应用程序建立、调度和管理用户级的线程。因此,可以很好地将内核级线程和用户级线程的优点结合起来。由此产生了不同的多线程模型。
-
多对一模型
多个用户级线程映射到一个内核级线程上- 线程管理由线程库在用户空间进行
- 一个用户线程若执行了阻塞系统调用,则整个进程会阻塞。
- 任一时刻一次只有一个线程能够访问内核
- 无法利用多核处理器目前很少系统采用这种模型
-
一对一模型
- 每个用户级线程映射到一个内核级线程上
- 一个用户线程阻塞时,允许其他线程继续执行。允许多线程并发运行在多处理器系统。但大量创建内核线程开销很大,因此实现中需要限制创建数量。
-
多对多模型
- 多个用户级线程映射到较少或相等个数的内核级线程上。可创建任意多的用户线程。
- 相应的内核线程能在多处理器系统上并发执行。
- 当一个线程执行阻塞系统调用,内核能调度另一个线程执行。
- 变种(二层模型):既允许多对多,也允许一对一绑定。