2.8 线程的实现

L13

学习目标

线程的实现方式分为内核支持线程和用户级线程,二者在调度单位和管理方式上存在差异。

  • 线程是进程内的执行单位,进程是资源分配单位;线程共享进程的地址空间和资源。
  • 线程实现方式:内核支持线程(由OS创建和管理)和用户级线程(由用户库创建和管理)。
  • 内核支持线程:OS知道线程存在,调度以线程为单位;用户级线程:OS不知道线程,调度以进程为单位。
  • 多对一模型:多个用户线程映射到一个内核线程;一对一模型:每个用户线程对应一个内核线程;多对多模型:多个用户线程映射到多个内核线程。

原理 · 深入理解

进程与线程:地址空间共享 进程 A(重) 代码+数据+堆+文件表 线程 T1 自己的栈 线程 T2 自己的栈 LiteOS-M 任务 Task ≈ 线程 同地址空间(MCU 单进程) 调度单位是 Task TCB 保存 sp / 优先级

2.8 线程的实现

本节概览:先建立「线程的实现」的框架,再依次展开下列小节。

  1. 线程的实现方式
  2. 线程的实现
  3. 线程的创建和终止

2.8.1 线程的实现方式

内核支持线程的优点

内核支持线程(KST)由内核创建、调度。这种实现常见有四条好处。

  1. 多处理器上,内核可同时调度同一进程里的多个线程并行执行
  2. 线程的数据结构和栈较小,切换较快、开销较小
  3. 内核本身也可采用多线程,提高执行效率
  4. 一个线程阻塞时,内核可调度同进程或其他进程的线程继续跑

用户级线程:优缺点

用户级线程(ULT)在用户空间实现,创建、撤销、同步通常不必陷入内核。优点和缺点要分开看。

优点:切换快、可定制

线程切换不必进内核;调度算法可以按应用定制;实现与具体 OS 内核平台耦合较弱。

缺点:一堵全堵

一个线程若因系统调用阻塞,同进程其它用户级线程往往也无法执行;同一进程里同一时刻通常只有一个 ULT 在执行。

组合方式 ULT/KST

有些系统把两种方式组合起来(ULT/KST):内核管理若干内核线程,应用仍可自己建立、调度用户级线程,兼顾灵活与真正的并行。

图2-18 多线程模型 线程 T1 · T2 · T3 调度单位 进程(资源单位) 地址空间 / 打开文件

2.8.2 线程的实现

在仅设置内核支持线程的 OS 中,一种可能的线程控制方法是:创建新进程时为它分配一个任务数据区 PTDA(Per Task Data Area),其中包含若干个线程控制块 TCB 空间。

此外还有两种支撑机制:运行时系统(Runtime System)和轻型进程 LWP(Light Weight Process)。

PTda

任务数据区,创建进程时分配,内含若干 TCB 空间,用于管理该进程的多个线程。

运行时系统

驻留用户空间的用于管理和控制线程的函数集合,包括创建撤销、同步通信、调度等函数,是用户级线程与内核之间的接口。

LWP

轻型进程,又称中间系统。每个 LWP 有自己的 TCB、栈和局部存储区,可共享进程资源,并能通过系统调用获得内核服务。

图2-19 任务数据区空间 高地址 任务数据区 共享区 低地址
图2-19 任务数据区空间

“运行时系统”实质上是用于管理和控制线程的函数(过程)的集合,其中包括用于创建和撤销线程的函数、线程同步和通信的函数,以及实现线程调度的函数等。正因为有这些函数,才能使用户级线程与内核无关。运行时系统中的所有函数都驻留在用户空间,并作为用户级线程与内核之间的接口。

运行时系统(Runtime System)。

又称为轻型进程LWP(Light Weight Process)。每一个进程都可拥有多个LWP,同用户级线程一样,每个LWP都有自己的数据结构(如TCB),其中包括线程标识符、优先级、状态,另外还有栈和局部存储区等。LWP也可以共享进程所拥有的资源。LWP可通过系统调用来获得内核提供的服务。

图2-20 利用轻型进程作为中间系统 用户线程 LWP 内核线程 轻型进程夹在中间
图2-20 利用轻型进程作为中间系统

2.8.3 线程的创建和终止

应用程序启动时通常只有一个线程在执行,称为初始化线程,它主要用于创建新线程。

创建新线程时需调用线程创建函数(或系统调用),并提供指向线程主程序入口的指针、堆栈大小、调度优先级等参数;函数执行完后返回一个线程标识符供后续使用。

线程完成任务或在运行中出现异常时,由终止线程调用相应函数(或系统调用)对其执行终止操作;但有些线程(主要是系统线程)一旦建立便一直运行而不被终止。

在大多数 OS 中,线程被终止后并不立即释放所占资源,只有当进程中的其他线程执行了分离函数后,被终止线程才与资源分离,资源才能被其他线程利用。

做 · 交互动画

  • 根据「学习目标」列出 3 个关键词,对照原理段落(2.8)解释给自己听。

线程的实现

用控件单步操作;日志区记下每一步发生了什么。

总结与提升

  • 能区分内核支持线程与用户级线程。
  • 能用自己的话复述学习目标,并指出与本课任务模型的对应。

延伸思考

  • 若引入用户态线程,HDF 驱动应放哪?
  • 如果把本节机制拿到 Linux 或完整 OpenHarmony 上,会多出哪些硬件假设?

← 本阶段封面 · 课程列表