Skip to content

ch4 线程

4.1 概述

  1. 线程概述
    • 线程时CPU使用的基本单元,它由线程ID、程序计数器、寄存器集合和堆栈组成
    • 它与属于同一进程的其他线程共享代码段,数据段和其他操作系统资源,如打开文件和信号
  2. 进程的两个基本特征
    1. 拥有资源的独立单位
    2. 独立调度和分派的基本单位
  3. 动机
    • OS中进程的引入是为了使多个程序并发执行,改善资源利用率,提高系统的吞吐量;OS中引入线程是为了减少程序并发执行时所付出的时空开销,使OS具有更好的并发性
    • 将进程的两个基本特征分开:作为调度和分派的基本单位,不同时作为独立分配资源的单位,使之轻装上阵;作为拥有资源的基本单位,不频繁对之进行切换。这种观点导致了线程的产生——是进程的一个实体,是被系统独立调度和分派的基本单位,自己基本不拥有资源,只拥有一点在运行中必不可少的资源(程序计数器、寄存器、栈),可与同属于一个进程的其他线程共享进程所拥有的资源
  4. 多线程编程的优点
    1. 响应度高:对一个交互程序采用多线程,即使其组成部分阻塞或执行较冗长的操作。该程序仍能继续执行,从而增加了用户的响应速度
    2. 资源共享:线程默认共享他们所属进程的内存和资源
    3. 经济:创建和切换线程很经济
    4. 多处理器体系结构的利用
  5. 进程与线程
    • 对于传统的OS来说,调度和分派的基本单位时进程,拥有资源的基本单位也是进程
    • 引入了线程的OS中,调度和分派的基本单位是线程,拥有资源的基本单位是进程
    • 线程能轻装上阵,可显著的提高系统的并发度
    • 同一进程中线程的切换不会引起进程的切换;不同进程中线程之间的切换要引起进程间的切换
    • 引入线程的系统的同一进程的多个线程之间可以并发的执行,使得系统有更好的并发性,进一步提高了资源的利用率和系统吞吐量
    • 同一进程的多个线程之间具有相同的地址空间,致使它们的同步和通信的实现更加容易

4.2 多线程模型

  1. 用户线程(User Thread)和内核线程(Kernel Thread)
    • 用户线程:仅存在于用户空间中。对于这种线程的创建、撤销、切换、线程之间的同步与通信等功能,都无需利用系统调用来实现,而是通过用户级线程库来实现。用户线程受内核支持,而无需内核管理
    • 内核线程:由操作系统直接支持和管理
  2. 用户线程和内核线程的映射模型
    • 用户级线程执行的时候要将线程映射到内核线程才能执行
    1. 多对一模型:将许多的用户线程映射到一个内核线程。用户线程管理由线程库在用户空间进行故故障率比较高 alt text 缺点:但是如果一个线程执行阻塞了系统调用,那么整个进程会阻塞。而且多个线程不能并行运行在多处理器上(任一时刻只有一个线程能访问内核)
    2. 一对一模型:将每个用户线程映射到一个内核线程。提供了比多对一模型更好的并发性能(在一个线程执行的时候阻塞了系统调用,能允许另一个线程继续执行)。允许多个线程并行地运行在多处理器系统上。 alt text
    • 缺点:会限制系统所支持的线程数量(一对一的创建内核线程的开销会影响应用程序的性能)
    1. 多对多模型:多路复用了许多用户线程到同样数量或更小数量的内核线程上。开发人员可以创建任意多的用户线程,并且相应的内核线程能在多处理器系统上并发执行。 alt text
    2. 二级模型:在多对多模型的基础上也允许将一个用户进程绑定到某个内核进程上 alt text
  3. 四种模型的比较
    • 多对一模型:可创建任意多的用户线程,不并发,不并行
    • 一对一模型:限制线程数量,并发,并行
    • 多对多模型:可创建任意多的用户线程,并发,并行
    • 二级模型:可创建任意多的用户线程,并发,并行

4.3 线程库

  1. 实现线程库的两种方法
    1. 在用户空间中提供一个没有内核支持的库(此库的所有代码和数据结构都存在于用户空间中),调用库中的一个函数只是导致了用户空间的一个本地函数调用,而不是系统调用
    2. 执行一个由操作系统支持的的内核级的库(库的代码和数据结构存在于内核空间中),调用库的一个API函数通常会导致对内核的系统调用
  2. 三种线程库
    1. POSIX线程(PThread)
    2. Win32线程
    3. Java线程

4.4 例题