26考研——进程与线程_线程和多线程模型(2)

408答疑



三、线程和多线程模型

提出线程的动机:
WEB 服务器需要同时处理多个客户请求
创建多个进程会降低响应时间
进程开销较大(上下文切换)

线程的基本概念

引入线程的目的

  • 减小程序在并发执行时所付出的时空开销;
  • 提高操作系统的并发性能。

引入进程的目的是更好地使多道程序并发执行,提高资源利用率和系统吞吐量。

线程的定义

  • 线程最直接的理解就是轻量级进程,它是一个基本的 CPU 执行单元,也是程序执行流的最小单元,由线程 ID、程序计数器、寄存器集合和堆栈组成。
  • 线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器、一组寄存器和栈),但它可与同属一个进程的其他线程共享进程所拥有的全部资源,如下图所示。

在这里插入图片描述

  • 一个线程可以创建和撤销另一个线程,同一进程中的多个线程之间可以并发执行。
  • 线程之间也会相互制约,使其在运行中呈现出间断性。

注意:
引入线程后,进程的内涵发生了改变,进程只作为除 CPU 外的系统资源的分配单元,而线程则作为 CPU 的分配单元。
由于一个进程内部有多个线程,若线程的切换发生在同一个进程内部,则只需要很少的时空开销。
线程必须在某个进程内执行,一个线程只属于一个进程。

线程与进程的比较和关系

线程与进程的比较

  1. 调度:

    • 在传统的操作系统中,拥有资源和独立调度的基本单位都是进程。每次调度都要进行上下文切换,开销较大。
    • 在引入线程的操作系统中,线程是独立调度的基本单位,而线程切换的代价远低于进程。
    • 在同一进程中,线程的切换不会引起进程切换。但从一个进程中的线程切换到另一个进程中的线程时,会引起进程切换。
  2. 并发性:

    • 在引入线程的操作系统中,不仅进程之间可以并发执行,而且一个进程中的多个线程之间亦可并发执行,甚至不同进程中的线程也能并发执行,从而使操作系统具有更好的并发性,提高了系统资源的利用率和系统的吞吐量。
  3. 拥有资源:

    • 进程是系统中拥有资源的基本单位,而线程不拥有系统资源(仅有一点必不可少的、能保证独立运行的资源),但线程可以访问其所属进程的系统资源,这主要表现在属于同一进程的所有线程都具有相同的地址空间。
    • 要知道,若线程也是拥有资源的单位,则切换线程就需要较大的时空开销,线程这个概念的提出也就没有意义。
  4. 独立性:

    • 每个进程都拥有独立的地址空间和资源,除了共享全局变量,不允许其他进程访问。
    • 某个进程中的线程对其他进程不可见。
    • 同一进程中的不同线程是为了提高并发性及进行相互之间的合作而创建的,它们共享进程的地址空间和资源。
  5. 系统开销:

    • 在创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O设备等。操作系统为此所付出的开销,明显大于创建或撤销线程时的开销。
    • 类似地,在进程切换时涉及进程上下文的切换,而线程切换时只需保存和设置少量寄存器内容,开销很小。
    • 此外,由于同一进程内的多个线程共享进程的地址空间,因此这些线程之间的同步与通信非常容易实现,甚至无须操作系统的干预。
  6. 支持多处理器系统:

    • 对于传统单线程进程,不管有多少个 CPU,进程只能运行在一个 CPU 上。
    • 对于多线程进程,可将进程中的多个线程分配到多个 CPU 上执行。

线程与进程的关系

  1. 从属关系:

    • 进程可以创建进程,也可以创建线程;线程可以创建其它的线程。
    • 一个进程至少要有一个可执行线程,但可以有多个线程;而一个线程只能在一个进程的地址空间内活动。
  2. 系统管理:

    • 进程是系统资源分配和拥有的单位,资源分配给进程,同一进程的所有线程共享该进程的所有资源。
    • 线程是系统调度执行的单位,处理机分配给线程,即真正在处理机上运行的是线程。
  3. 工作效率:

    • 创建线程比创建进程快,进程内的线程切换也比进程快,且节省开销。
    • 在 Solaris 中,创建线程比进程快 30 倍,线程切换比进程切换快 5 倍。
    • 从而获得快速的用户响应,如在 C/S 模式下,web server 为每个用户连接运行一个线程。
  4. 并发效果:

    • 用线程实现并发/并行比用进程实现更方便更有效,特别是进程内的并发/并行。
    • 进程可创建多个线程来执行同一个程序的不同部分,从而实现进程内的并发。
    • 在多处理器体系结构,可以使一个进程中的线程在不同的处理器上运行,提高进程执行的并行性。

线程的属性

  • 多线程操作系统中的进程已不再是一个基本的执行实体,但它仍具有与执行相关的状态。
  • 所谓进程处于“执行”状态,实际上是指该进程中的线程正在执行。
  • 线程的主要属性如下:
    1. 线程是一个轻型实体,它不拥有系统资源,但每个线程都应有一个唯一的标识符和一个线程控制块,线程控制块记录线程执行的寄存器和栈等现场状态。
    2. 不同的线程可以执行相同的程序,即同一个服务程序被不同的用户调用时,操作系统将它们创建成不同的线程。
    3. 同一进程中的各个线程共享该进程所拥有的资源。
    4. 线程是 CPU 的独立调度单位,多个线程是可以并发执行的。
      • 在单 CPU 的计算机系统中,各线程可交替地占用 CPU;
      • 在多 CPU 的计算机系统中,各线程可同时占用不同的 CPU,若各个 CPU 同时为一个进程内的各线程服务,则可缩短进程的处理时间。
    5. 一个线程被创建后,便开始了它的生命周期,直至终止。线程在生命周期内会经历阻塞态、就绪态和运行态等各种状态变化。

为什么线程的提出有利于提高系统并发性?
可以这样来理解:
由于有了线程,线程切换时,有可能会发生进程切换,也有可能不发生进程切换,平均而言每次切换所需的开销就变小了,因此能够让更多的线程参与并发,而不会影响到响应时间等问题。

线程的状态与转换

与进程一样,各线程之间也存在共享资源和相互合作的制约关系,致使线程在运行时也具有间断性。相应地,线程在运行时也具有下面三种基本状态。

  • 执行态:线程已获得 CPU 而正在运行。
  • 就绪态:线程已具备各种执行条件,只需再获得 CPU 便可立即执行。
  • 阻塞态:线程在执行中因某事件受阻而处于暂停状态。

线程这三种基本状态之间的转换和进程基本状态之间的转换是一样的。

线程的组织与控制

线程控制块

  • 与进程类似,系统也为每个线程配置一个线程控制块 TCB,用于记录控制和管理线程的信息。

  • 线程控制块通常包括:

    1. 线程标识符;
    2. 一组寄存器,包括程序计数器、状态寄存器和通用寄存器;
    3. 线程运行状态,用于描述线程正处于何种状态;
    4. 优先级;
    5. 线程专有存储区,线程切换时用于保存现场等;
    6. 堆栈指针,用于过程调用时保存局部变量及返回地址等。
  • 同一进程中的所有线程都能访问进程的地址空间和全局变量。

  • 但是,每个线程都拥有自己的堆栈,且互不共享(可以这么理解:线程的堆栈被包含在进程的地址空间内,因此同一进程中的各个线程事实上可以访问彼此的堆栈,但编程规范通常不推荐这么做)。

线程的创建

  • 线程也是具有生命周期的,它由创建而产生,由调度而执行,由终止而消亡。相应地,在操作系统中就有用于创建线程和终止线程的函数(或系统调用)。
  • 用户程序启动时,通常仅有一个称为初始化线程的线程正在执行,其主要功能是用于创建新线程。
  • 在创建新线程时,需要利用一个线程创建函数,并提供相应的参数,如指向线程主程序的入口指针、堆栈的大小、线程优先级等。
  • 线程创建函数执行完后,将返回一个线程标识符。

线程的终止

  • 当一个线程完成自己的任务后,或线程在运行中出现异常而要被强制终止时,由终止线程调用相应的函数执行终止操作。但是有些线程(主要是系统线程)一旦被建立,便一直运行而不会被终止。
  • 通常,线程被终止后并不立即释放它所占有的资源,只有当进程中的其他线程执行了分离函数后,被终止线程才与资源分离,此时的资源才能被其他线程利用。
  • 被终止但尚未释放资源的线程仍可被其他线程调用,以使被终止线程重新恢复运行。

线程的实现方式

线程的实现可以分为两类:用户级线程(User-Level Thread,ULT)和内核级线程(Kernel-Level Thread,KLT)。内核级线程也称内核支持的线程。

用户级线程 (ULT)

  • 用户级线程是“从用户视角能看到的线程”。
  • 在用户级线程中,线程管理(创建、撤销和切换等)的所有工作都由应用程序在用户空间内完成,无须操作系统干预,内核意识不到线程的存在。
  • 应用程序可以通过使用线程库设计成多线程程序。通常,应用程序从单线程开始,在运行的任何时刻,可以通过调用线程库中的派生例程创建一个在相同进程中运行的新线程。
  • 下图说明了用户级线程的实现方式。

在这里插入图片描述

  • 优点:
    1. 线程切换不需要转换到内核空间,节省了模式切换的开销。
    2. 调度算法可以是进程专用的,不同的进程可根据自身需要,对自己的线程选择不同的调度算法。
    3. 用户级线程的实现与操作系统平台无关,对线程管理的代码是属于用户程序的一部分。
  • 缺点:
    1. 系统调用的阻塞问题,当线程执行一个系统调用时,不仅该线程被阻塞,进程内的所有线程也都被阻塞。
    2. 不能发挥多 CPU 的优势,内核每次分配给一个进程的仅有一个 CPU,因此进程中仅有一个线程能执行。

注意:
对于设置了用户级线程的系统,其调度仍然以进程为单位进行,各个进程轮流执行一个时间片。
假设进程 A 包含 1 个用户级线程,进程 B 包含 100 个用户级线程,这样,进程 A 中线程的运行时间将是进程 B 中各线程运行时间的 100 倍,因此对线程来说实质上是不公平的。

内核级线程 (KLT)

  • 在操作系统中,无论是系统进程还是用户进程,都是在操作系统内核的支持下运行的,与内核紧密相关。
  • 内核级线程也是在内核的支持下运行的,线程管理的所有工作也是在内核空间内(内核态)完成的。
  • 操作系统也为每个内核级线程设置一个线程控制块 TCB,内核根据该控制块感知某线程的存在,并对其加以控制。
  • 下图说明了内核级线程的实现方式。

在这里插入图片描述

  • 优点:
    1. 能发挥多 CPU 的优势,内核能同时调度同一进程中的多个线程并行执行。
    2. 如果进程中的一个线程被阻塞,内核可以调度该进程中的其他线程占用 CPU,也可运行其他进程中的线程。
    3. 内核支持线程具有很小的数据结构和堆栈,线程切换比较快,开销小。
    4. 内核本身也可采用多线程技术,可以提高系统的执行速度和效率。
  • 缺点:
    1. 同一进程中的线程切换,需要从用户态转到核心态进行,系统开销较大。这是因为用户进程的线程在用户态运行,而线程调度和管理是在内核实现的。

混合线程(组合方式)

  • 有些系统使用组合方式的多线程实现。
  • 在组合实现方式中,内核支持多个内核级线程的建立、调度和管理,同时允许用户程序建立、调度和管理用户级线程。
  • 一些内核级线程对应多个用户级线程,这是用户级线程通过时分多路复用内核级线程实现的。
  • 同一进程中的多个线程可以同时在多 CPU 上并行执行,且在阻塞一个线程时不需要将整个进程阻塞,所以组合方式能结合 KLT 和ULT 的优点,并且克服各自的不足。
  • 下图展示了这种组合实现方式。

在这里插入图片描述

  • 在线程实现方式的介绍中,提到了通过线程库来创建和管理线程。线程库(thread library)是为程序员提供创建和管理线程的 API。
  • 实现线程库主要的方法有两种:
    1. 在用户空间中提供一个没有内核支持的库。这种库的所有代码和数据结构都位于用户空间中。这意味着,调用库内的一个函数只导致用户空间中的一个本地函数的调用。
    2. 实现由操作系统直接支持的内核级的库。对于这种情况,库内的代码和数据结构位于内核空间。调用库中的一个 API 函数通常会导致对内核的系统调用

目前使用的三种主要线程库是:POSIX Threads、Windows API、Java。Pthreads 作为 POSIX 标准的扩展,可以提供用户级或内核级的库。

  • Windows API 是用于 Windows 系统的内核级线程库。
  • Java 线程 API 允许线程在 Java 程序中直接创建和管理。
  • JVM 实例通常运行在宿主操作系统之上,Java 线程 API 通常采用宿主系统的线程库来实现,因此在 Windows 系统中 Java 线程通常采用 Windows API 来实现,在类 UNIX 系统中采用 Pthreads 来实现。

多线程模型

在同时支持用户级线程和内核级线程的系统中,用户级线程和内核级线程连接方式的不同,形成了下面三种不同的多线程模型。

多对一模型

  • 将多个用户级线程映射到一个内核级线程,如下图所示。

在这里插入图片描述

  • 每个进程只被分配一个内核级线程,线程的调度和管理在用户空间完成。
  • 仅当用户线程需要访问内核时,才将其映射到一个内核级线程上,但每次只允许一个线程进行映射。
  • 优点:线程管理是在用户空间进行的,无须切换到内核态,因此效率比较高。
  • 缺点:若一个线程在访问内核时发生阻塞,则整个进程都会被阻塞;在任何时刻,只有一个线程能够访问内核,多个线程不能同时在多个 CPU 上运行。

一对一模型

  • 将每个用户级线程映射到一个内核级线程,如下图所示。

在这里插入图片描述

  • 每个进程有与用户级线程数量相同的内核级线程,线程切换由内核完成,需要切换到内核态。
  • 优点:当一个线程被阻塞后,允许调度另一个线程运行,所以并发能力较强。
  • 缺点:每创建一个用户线程,相应地就需要创建一个内核线程,开销较大。

多对多模型

  • n n n 个用户级线程映射到 m m m 个内核级线程上,要求 n ≥ m n \geq m nm,如下图所示。

在这里插入图片描述

  • 特点:既克服了多对一模型并发度不高的缺点,又克服了一对一模型的一个用户进程占用太多内核级线程而开销太大的缺点。此外,还拥有上述两种模型各自的优点。

七、参考资料

鲍鱼科技课件

b站免费王道课后题讲解:
在这里插入图片描述

网课全程班:
在这里插入图片描述

26王道考研书

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

408答疑+v:18675660929

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值