理解计算中的线程:开发者实用指南

发布: (2025年12月19日 GMT+8 11:46)
8 min read
原文: Dev.to

It looks like only the source line was provided. Could you please share the text you’d like translated? Once I have the content, I’ll translate it into Simplified Chinese while keeping the source link and formatting unchanged.

什么是线程?

线程是操作系统可以调度的最小执行单元。它代表一系列可以在进程内部独立运行的指令。

关键点

  • 进程是正在运行的程序的实例。
  • 线程是该进程内部的执行路径。
  • 单个进程可以包含多个线程

你可以把进程想象成拥有资源的容器,而线程则是使用这些资源执行代码的工作者。

进程 vs 线程

了解进程和线程之间的区别至关重要。

进程

  • 拥有自己的虚拟地址空间
  • 拥有系统资源(内存、文件句柄、套接字)
  • 创建和销毁时开销大
  • 与其他进程相互隔离

线程

  • 共享进程的地址空间
  • 与同一进程中的其他线程共享资源
  • 相对于进程来说更轻量
  • 可以直接访问共享内存

这种共享内存模型功能强大,但也是许多并发错误的根源。

为什么会有线程

  1. 并行性 – 在多核 CPU 上,线程允许真正的并行执行。多个线程可以在不同的核心上同时运行,提高吞吐量并缩短执行时间。
  2. 响应性 – 在交互式应用程序中,线程保持系统的响应。
    • 一个线程处理用户输入
    • 另一个线程执行后台工作
      没有线程,长时间运行的操作会阻塞整个程序。
  3. 资源利用率 – 线程有助于高效利用 CPU 资源,尤其是当任务涉及等待(I/O、网络、磁盘操作)时。

线程生命周期

线程通常会经历以下状态:

  • New – 线程已创建但尚未启动
  • Runnable – 线程已准备好运行,正在等待 CPU 时间
  • Running – 线程当前正在 CPU 上执行
  • Blocked / Waiting – 线程正在等待资源或事件
  • Terminated – 线程已完成执行

操作系统的调度程序控制这些状态之间的转换。

操作系统如何管理线程

调度

操作系统调度器决定:

  • 哪个线程运行
  • 在哪个 CPU 核心上运行
  • 运行多长时间

现代调度器使用抢占式多任务,这意味着正在运行的线程可以被中断,以给其他线程分配 CPU 时间。

上下文切换

当 CPU 从一个线程切换到另一个线程时,会执行 上下文切换

  1. 保存当前线程的寄存器和状态
  2. 加载下一个线程的状态

上下文切换速度快,但不是没有代价。过度切换会影响性能。

用户级线程 vs 内核线程

内核线程

  • 直接由操作系统管理
  • 可以在多个核心上真正并行运行
  • 开销更高

用户级线程

  • 由运行时或库管理
  • 创建和切换更快
  • 受限于操作系统的调度模型

许多现代运行时(例如 JVM 或 Go)采用混合方式。

Source:

共享内存与同步

因为线程共享内存,同步是必需的,以防止数据损坏。

常见问题

  • 竞争条件 – 多个线程并发修改共享数据
  • 死锁 – 线程相互无限等待
  • 饥饿 – 线程永远得不到 CPU 时间
  • 数据不一致 – 部分更新对其他线程可见

同步工具

  • 互斥锁(锁)
  • 信号量
  • 条件变量
  • 原子操作
  • 读写锁

正确的同步至关重要,但很难做到完美。

线程安全

如果一段代码在被多个线程同时访问时能够正确运行,则称其 线程安全

线程安全设计原则

  • 最小化共享状态
  • 优先使用不可变对象
  • 将关键区段保持简短
  • 尽可能避免加锁

线程安全不是自动实现的——必须有意识地进行设计。

性能考虑

线程可以提升性能,但使用不当会导致系统变慢。

常见错误

  • 创建过多线程
  • 过度使用锁
  • 不必要地阻塞线程
  • 忽视缓存一致性影响

一个好的准则:线程越多并不一定意味着性能更好

线程 vs 异步编程

线程并不是唯一的并发模型。

线程

  • 共享内存
  • 抢占式调度
  • 复杂的同步

异步 / 事件驱动模型

  • 协作式调度
  • 显式状态机
  • 对 I/O 密集型工作负载的开销更低

现代系统通常会结合两种方法。

实际案例

线程被广泛用于:

  • Web 服务器(请求处理)
  • 数据库(查询执行)
  • 游戏引擎(渲染、物理、AI)
  • 操作系统
  • 编译器和构建系统

在每一种情况下,目标都是实现受控的并发并保证行为可预测。

最佳实践指南(开发者)

  • 理解所使用语言的内存模型
  • 在进行优化之前先测量性能
  • 追求简洁胜于巧妙
  • 在有可用的情况下使用高级并发抽象
  • 对并发进行处理

并发错误作为设计缺陷,而非边缘情况

Conclusion

线程是现代计算的基本构件。它们实现并行性、响应性和高效的资源使用——但也带来复杂性和风险。精通线程不仅需要了解如何创建它们,还要理解它们与内存、操作系统以及彼此之间的交互。

深刻理解线程的开发者更有能力设计出快速、可扩展且正确的系统。如果你目标是编写高性能软件,线程不是可选的知识——它们是必不可少的。

Back to Blog

相关文章

阅读更多 »