线程

义项:线程
线程

线程(thread)是操作系统能够进行运算调度的最小单位,包含在进程之内,是进程中的实际运作单位。一条线程是进程中一个单一顺序的控制流,同一进程可以并发多条线程,并共享该进程的地址空间与已打开文件等资源,仅各自保留程序计数器、寄存器和栈等运行时私用部分。由于创建、切换和销毁线程的开销低于进程,线程成为实现并发与利用多核处理器的基本手段,多线程编程也由此成为现代软件开发中的常见模型[1]。

目录
  1. 定义
  2. 原理
  3. 发展历程
  4. 应用
  5. 局限
  6. 参见

定义

线程指程序执行过程中的一条单一顺序控制流,是操作系统进行调度和分派的基本单位。它不能脱离进程独立存在,每个进程至少拥有一个线程,程序启动时最先建立的那条线程通常称为主线程[1]。

操作系统理论把资源所有权与执行调度两项职能分开:进程作为资源的容器,持有地址空间、打开的文件和用户信息等;线程则是被调度的执行实体[2]。因此同一进程内的多条线程共享该进程的代码、全局数据和堆,但各自拥有独立的栈、局部变量、寄存器和程序计数器[3]。

在 Unix System V 和 SunOS 等系统中,线程也曾被称为轻量进程(lightweight processes),不过这一称呼后来更多用于指内核线程,用户线程才直接叫线程。

原理

线程的运作依赖处理器上下文的概念。每条线程对应一组寄存器状态、一个栈和一段可执行代码,内核在切换线程时保存当前上下文并恢复目标线程的上下文,这一过程称为上下文切换。由于同进程线程共用页表与地址空间,切换时无须更换地址空间,因此开销小于进程切换[2]。

按照调度由谁完成,线程可分为用户级线程与内核级线程两类。用户级线程由应用程序内的线程库创建和管理,内核只看到进程,因而不必陷入内核态,切换很快,但一条线程发生阻塞时整个进程都会受阻[4]。内核级线程由内核直接维护和调度,某条线程阻塞不影响同进程其他线程,代价是创建与切换需在用户态和内核态之间往返[4]。

用户线程与内核线程的对应关系常用三种模型描述:N:1 模型把多条用户线程映射到单个内核调度实体,1:1 模型让每条用户线程独占一个内核线程,N:M 模型则把 N 条用户线程复用到 M 个内核调度实体上[5]。N:1 实现简单且切换极快,但同一时刻只有一条线程能被调度,无法借助多处理器;N:M 兼顾两者,却需要用户态调度器与内核调度器之间的协调,实现复杂度最高[5]。

并行与并发是两个相关但有区别的概念:并行指多个处理器在同一时刻真正同时执行多个任务,并发指单个处理器按时间片轮转处理多个任务[3]。在线程数不超过处理器数时,多条线程可以真正并行;超过时则主要依靠轮转获得并发的效果。

发展历程

20 世纪 60 年代,操作系统中同时承担资源拥有与独立运行职能的基本单位是进程。随着计算机技术演进,进程作为资源拥有者,其创建、撤销与切换带来较大的时间和空间开销,同时对称多处理机(SMP)的出现要求系统能提供多个可并行运行的执行单位,而多进程并行的开销过大,于是需要更轻量的执行体。到 20 世纪 80 年代,能够独立运行的线程作为基本单位出现,此后通用操作系统陆续引入线程机制,并将其视为衡量现代操作系统并发能力的重要指标。

Linux 的线程支持经历了较长演变。早期内核并无真正意义上的线程,常用线程库借助进程模拟;1996 年 Linux 首次借助 clone() 系统调用获得内核级线程支持,当时使用的函数库为 LinuxThreads,采用一对一线程模型,但受信号处理与调度语义所限,并不完全符合 POSIX 标准[6]。Linux 2.6 内核引入线程组与 tgid 字段,随后以原生 POSIX 线程库(NPTL)取代 LinuxThreads,并借助 futex 机制处理线程同步,使其更贴近标准[7]。

硬件层面同样出现线程相关技术。超线程由英特尔于 2002 年在至强服务器处理器与奔腾 4 桌面处理器上首次推出,它把单个物理核心划分为两个逻辑核心,使操作系统把每个物理核心识别为两个虚拟核心,从而在一个核心上同时调度多条线程,提高处理器利用率[8]。这种技术属于硬件层面的实现,编程时无须额外改写代码,但能提供的处理能力不及多核并行[8]。

应用

线程最直接的价值在于提高处理器与输入输出资源的利用率。当某条线程因等待输入输出而让出处理器时,其他线程可以继续运行,从而减少处理器的空闲时间。在服务器端,数据库服务、网络服务和大容量计算等需要同时处理多个请求的场景,常用多线程组织并发任务[2]。

图形用户界面是另一类典型场合。程序把耗时操作放入独立线程,界面线程得以继续响应按键与绘图请求,用户无须等待当前任务完成[9]。文件读写、网络通信和图像处理等可分解且彼此依赖较少的任务,也常被拆成多条线程并行执行[8]。

在编程语言层面,线程通常以库或语言内建机制提供。Java 把多线程支持内建到语言之中,线程在对象一级得到支持,并可用 synchronized 关键字对共享内存加锁[9];其 Thread 类可视为对操作系统线程接口的进一步封装[1]。Python 的 threading 模块在单个进程内操作,所有线程共享同一内存空间[10]。

当线程创建与销毁过于频繁时,程序常改用线程池管理一组可复用线程,以减少反复建立线程的开销。

局限

多线程并不必然带来性能提升。线程本身要占用内存,开启大量线程会消耗大量内存并抬高处理器在调度上的开销,在内存紧张时反而成为负担[11]。频繁的上下文切换也会拖慢执行速度,程序并发所需的时间可能被调度开销抵消[3]。

资源共享是线程模型固有的难点。多条线程同时访问同一数据时可能产生竞争,需要借助锁、信号量等同步手段保证一致性,而多个线程相互等待对方持有的资源时可能形成死锁。为此程序设计需更谨慎,线程间通信与共享数据的处理都会增加复杂度[11]。

某些语言运行环境对线程并行设有额外限制。CPython 中的全局解释器锁使同一时刻只有一条线程执行 Python 代码,CPU 密集型任务难以靠多线程提速,此类场景更适合多进程方案;而 I/O 密集型任务仍适合用多线程处理[10]。此外,用户级线程模型下一条线程阻塞即导致整个进程阻塞,也限制了其适用范围[4]。

并行效果还受硬件与资源条件制约。当线程数超过处理器数量时,并发主要靠时间片轮转实现,并非真正同时执行[3];若并发部分仍受硬件或软件资源限制而只能串行,程序还会因额外的调度开销而变慢[3]。超线程提供的并行能力也弱于真正的多核,并可能引起资源争用和缓存冲突[8]。

参见

  • 进程 —— 操作系统资源分配的基本单位,线程包含于其中并共享其资源。

  • 多线程 —— 在同一程序内同时运行多条线程以并发执行不同任务的编程方式。

  • 线程池 —— 预先创建并复用一组线程、减少频繁创建销毁开销的管理机制。

  • 协程 —— 比线程更轻量的用户态并发执行单位,由程序自行调度。

  • 上下文切换 —— 保存当前执行状态并恢复另一执行状态的过程,决定线程切换的开销。

  • 超线程 —— 把单个物理核心虚拟为两个逻辑核心、以硬件方式支持多线程的技术。

参考资料

  1. 【JavaEE初阶】一文带你了解线程、多线程基础 [引用日期2026-10-29]
  2. 内核线程、轻量级进程、用户线程三种线程概念解惑(线程≠轻量级进程)【转】 [引用日期2026-10-29]
  3. 并发 [引用日期2026-10-29]
  4. 操作系统中的进程和线程 [引用日期2026-10-29]
  5. google.com 上的网页 [引用日期2026-10-29]
  6. aliyun.com 上的网页 [引用日期2026-10-29]
  7. ic619199 [引用日期2026-10-29]
  8. 多线程 vs. 超线程 [引用日期2026-10-29]
  9. github.com 上的网页 [引用日期2026-10-29]
  10. threading --- 基于线程的并行 [引用日期2026-10-29]
  11. Java部分-9线程答案 [引用日期2026-10-29]
词条评价
词条统计

浏览次数:0 次

阅读量:0 次 · 阅读完成量:0 次

最近更新:2026-10-28T19:02:25Z

历史版本

本条目引用的词条
进程 多线程 线程池 协程 上下文切换 超线程