操作系统笔记之CPU、核心、进程、线程与并行并发的关系全解析
操作系统笔记之CPU、核心、进程、线程与并行并发的关系全解析

code review!
文章目录
一、基础概念:CPU、核心、进程、线程的关系
这四个概念是计算机核心架构与程序执行的基础。我们可以把 CPU 比作一家"大型工厂",用这个拟人化的视角来理清它们之间的层级和协作关系。
1.1 核心概念拆解
1.1.1 🏛️ CPU(中央处理器):工厂总部
CPU 是整台计算机的大脑。如果把计算机比作一个工业园区,CPU 就是那个核心的"制造总厂"。它负责协调、管理和执行所有的计算任务。
1.1.2 核心数量(Cores):独立的生产车间
早期的 CPU 只有一个核心,相当于工厂只有一个车间。现代 CPU 都是"多核"的(如 4 核、8 核、16 核)。
- 核心是真正动手做计算的物理硬件单元。
- 核心数量越多,意味着工厂里的独立车间越多。4 核 CPU 意味着有 4 个车间可以真正同时(并行)干活。
1.1.3 进程(Process):承接的"大项目"
当打开一个软件(如 Chrome 浏览器、微信、游戏),操作系统就会为它创建一个进程。
- 进程是操作系统分配资源(如内存空间、显卡、文件句柄)的基本单位。
- 在工厂里,进程就像是一个个独立的"大项目"或"签约子公司"。每个项目(进程)都有自己独立的办公场地和预算(独立的内存空间),彼此隔离,互不干扰。如果一个项目搞砸了(崩溃了),不会直接导致隔壁项目倒闭。
1.1.4 线程(Thread):车间里的"流水线工人"
一个进程为了完成任务,会把工作拆分成更小的步骤,这些步骤由线程来执行。
- 线程是 CPU 调度和分配执行时间的基本单位。
- 在工厂里,线程就是项目组请来的"工人"或"生产流水线"。一个项目(进程)里可以包含一个或多个工人(线程)。
- 关键点: 同一个项目组内的所有工人(同个进程内的所有线程),是共享该项目的办公场地和资源(内存空间)的。因此,工人们沟通成本很低,但如果两个工人同时争夺同一个工具(死锁),或者一个工人把办公室拆了(内存溢出),整个项目(进程)就会垮掉。
1.2 进程与线程的深层对比
为了让它们动起来,我们需要理解它们是如何协同工作的:
| 维度 | 进程 (Process) | 线程 (Thread) |
|---|---|---|
| 资源拥有 | 拥有独立的内存和系统资源 | 共享所属进程的资源,几乎不拥有独立资源 |
| 独立性 | 进程间相互独立,安全性高 | 线程崩溃可能导致整个进程崩溃 |
| 切换开销 | 切换时需要保存/恢复大量资源,开销大 | 切换只需保存少量寄存器状态,开销小 |
| 关系 | 1 个 CPU 可以运行 N 个进程;1 个进程 必须包含 1 个或多个线程 | — |
1.3 一句话总结
CPU (总厂) → 核心 (车间) → 进程 (项目/资源分配) → 线程 (工人/执行单元) \text{CPU (总厂)} \rightarrow \text{核心 (车间)} \rightarrow \text{进程 (项目/资源分配)} \rightarrow \text{线程 (工人/执行单元)} CPU (总厂)→核心 (车间)→进程 (项目/资源分配)→线程 (工人/执行单元)
- CPU 提供了整个算力平台。
- 核心数量 决定了工厂同时开工的最高物理上限。
- 进程 负责向系统要一块独立的内存(圈地盖项目)。
- 线程 在进程的内存里真正跑腿执行代码。
二、并行与并发
2.1 基本定义
并行(Parallelism)是指在同一时刻,多个任务在不同的处理器核心上同时执行。
并发(Concurrency)是指在同一时间段内,多个任务交替执行,宏观上看起来像是同时进行,但微观上可能是单核交替切换。
2.2 并行(Parallelism):真正的"双管齐下"
- 定义:在同一时刻,多个任务由不同的硬件核心同时执行。
- 硬件前提:必须是多核 CPU(或多个 CPU)。
- 例子:有 2 个核心,核心 A 正在处理"游戏渲染线程",核心 B 正在处理"音乐播放线程"。它们在同一微秒内都在运转,互不干扰。
2.3 并发(Concurrency):高明的时间管理大师
- 定义:在一段时间内,多个任务交替执行,宏观上看起来像是在同时运行。
- 硬件前提:单核 CPU 就能做到,多核 CPU 在面对超额任务时也在用它。
- 例子:单核 CPU 要同时运行"微信"和"网易云音乐"。CPU 先让微信运行 0.01 秒,再让网易云运行 0.01 秒。因为切换速度是纳秒级的,感觉音乐没停,微信也能收到消息。
三、核心数、进程数、线程数、并行、并发的关系网
3.1 数量关系:核心数 vs 进程数 vs 线程数
它们在数量上没有硬性的比例死规定,但遵循以下生存法则:
- 进程数 ≥ \ge ≥ 1:只要电脑开机,操作系统本身就是一堆进程。
- 线程数 ≥ \ge ≥ 进程数:因为每一个进程至少包含一个主线程。如果开了 50 个进程,那总线程数绝对大于 50。
- 核心数与它们无关:核心数是硬件,进程和线程是软件。无论 CPU 是 4 核还是 64 核,都可以创造出成千上万个进程和线程。硬件核心数决定的是它们执行的效率,而不是数量的上限。
3.2 核心数量与线程的"并发"魔法
可能会问:“我的手机是 8 核的,但我同时开了几十个 App(进程),里面有几百个线程,这怎么跑得通?”
这就涉及到 CPU 的调度机制:
- 真·并行(Parallelism): 如果 CPU 有 8 个核心,那么在绝对同一时刻,它可以让 8 个线程在不同的车间里同时执行。
- 伪·并发(Concurrency): 面对几百个线程,CPU 核心会玩"分身术"(时间片轮转)。核心 1 先帮线程 A 拧 1 毫秒螺丝,然后马上换线程 B 拧 1 毫秒,接着换线程 C……由于切换速度极快(每秒几亿次),在人类看来,所有的程序都在"同时"运行。
3.3 五者的终极关系与经典场景
我们可以用一个公式和三个场景,把这五个概念串联起来:
最大并行线程数 = CPU 物理核心数 × 每核超线程数 \text{最大并行线程数} = \text{CPU 物理核心数} \times \text{每核超线程数} 最大并行线程数=CPU 物理核心数×每核超线程数
3.3.1 场景 A:任务少于核心数(纯并行)
- 状态:4 核 CPU,系统当前一共只有 3 个线程需要计算。
- 结果:CPU 挑出 3 个核心,每个核心认领一个线程。此时不需要切换,这是纯并行状态,效率最高。
3.3.2 场景 B:任务远超核心数(并行 + 并发)
- 状态:4 核 CPU,但开了几十个软件,系统里有 200 个线程在嗷嗷待哺。
- 结果:在任何一个绝对的瞬间,4 个核心只能并行处理 4 个线程。但为了让这 200 个线程都活下去,4 个核心开始疯狂玩"分身术",在 200 个线程之间高频切换(并发)。此时,系统处于"宏观并行,微观并发"的状态。
3.3.3 场景 C:进程与线程的内部协作
- 状态:正在用 Chrome 浏览器(1 个进程)下载电影、看网页、播视频(3 个不同的线程)。
- 结果:
- 如果操作系统把这 3 个线程分配给了 3 个不同的 CPU 核心,那它们之间就是并行。
- 如果系统当时很忙,把这 3 个线程都塞给了同一个 CPU 核心去轮流处理,那它们之间就是并发。
- 但不论如何,它们都必须共享 Chrome 这个进程向系统申请到的那块内存。
3.4 黄金口诀
- 核心数是车间,进程数是独立项目,线程数是干活工人。
- 工人比车间多时,工人们就得轮流用设备(并发)。
- 车间足够多时,不同的工人可以各自霸占一个车间同时干活(并行)。
四、深入探讨:核心数量与进程数量的关系
前面把更多篇幅放在了"核心-线程(执行单元)"以及"并发-并行"的组合上,而对"核心数量"与"进程数量"之间的直接关系着墨较少。
事实上,核心数量与进程数量之间没有直接的物理绑定关系,它们是通过"操作系统"和"线程"作为纽带进行间接管理的。
4.1 核心数量并不限制进程数量的上限
在现代操作系统(Windows, macOS, Linux)中,拥有多少个物理核心(比如 8 核),绝对不会限制只能运行多少个进程。
- 进程的本质是资源容器:当打开一个软件,操作系统会为它分配独立的内存、句柄等资源,这个过程几乎不消耗 CPU 核心的算力,它主要消耗的是内存(RAM)。
- 为什么能"以少控多":即使是单核(1 Core)CPU,也能同时创建几百个进程。因为进程本身只是躺在内存里的一个"任务包裹",只要内存足够大(比如 16GB 或 32GB),就可以创建成百上千个进程。核心数量决定的是"同时处理这些进程的速度",而不是"能容纳多少个进程"。
4.2 核心如何处理进程?(必须通过线程)
CPU 核心在硬件层面上,其实根本不知道什么是"进程"。CPU 核心唯一能看懂并执行的,是线程里的指令。
- 间接关系链:
物理核心 ⟺ 线程 ⟺ 进程 \text{物理核心} \Longleftrightarrow \text{线程} \Longleftrightarrow \text{进程} 物理核心⟺线程⟺进程
- 调度真相:操作系统(OS)的调度器负责看管所有的进程。当进程 A 需要干活时,它会派出自己的"员工"(线程 1)。操作系统随后把这个"线程 1"分配给"核心 1"去执行。
- 换言之:核心数量与进程数量的交互,完全取决于该进程内活跃线程的数量。如果一个进程处于后台静默状态(比如打开了微信但没聊天,其线程处于休眠状态),那它对 CPU 核心的占用率就是 0%,此时无论有多少个核心,都与这个进程无关。
4.3 多核 CPU 对多进程带来的实质改变
虽然核心数不限制进程数,但多核 CPU 能够显著提升多进程并发/并行时的系统性能和稳定性。具体体现在以下两个方面:
4.3.1 进程级别的真·并行(沙箱隔离)
在单核时代,如果一边玩大型游戏(进程 A),一边后台运行杀毒软件全面扫描(进程 B),游戏一定会卡顿。因为单核 CPU 必须在两个高负载的进程之间疯狂切换(并发)。
而在多核 CPU 下:
- 核心 1、2、3 可以全力以赴去跑游戏进程的线程。
- 核心 4 可以被操作系统分给杀毒软件进程。
通过这种方式,不同的进程真正实现了物理上的"并行"。由于进程间内存是隔离的,这种基于多核的进程划分能带来极高的系统流畅度。
4.3.2 现代多进程架构的完美搭档(以 Chrome 为例)
现代许多软件(如 Chrome 浏览器、飞书、VS Code)为了防止单个页面崩溃导致整个软件死机,采用了"多进程架构"。每开一个网页标签,Chrome 就会在后台新建一个独立的进程。
- 拥有更多的核心数量,意味着系统可以把这些密集的浏览器进程分散到不同的核心上同步处理。
- 即使某个网页进程突然遭遇死循环(100% 跑满一个核心),操作系统也只会让那一个核心卡死,其余的核心依然可以流畅地处理其他网页进程或系统进程。
4.4 高速公路总结
- 核心数(Hardware):代表"高速公路的运行带宽"和"物理车道数"。
- 进程数(Software):代表"登记在册的运输公司总数"(消耗的是车库/内存空间)。
- 线程数(Execution):代表"真正开上公路的货车"。
核心数量多,意味着可以允许更多不同的"运输公司(进程)"的"货车(线程)"同时在路上并排奔跑(并行),或者在路况拥堵时更从容地分流(并发),从而保证整个系统的稳定与流畅。
五、超线程是如何实现的?
超线程(Hyper-Threading,简称 HT)是英特尔(Intel)提出的一种硬件技术(在 AMD 处理器中被称为 SMT,同步多线程)。
简单来说,它的核心魔法是:利用"欺骗"操作系统和"榨干"核心内部闲置硬件的手段,让一个物理核心在软件眼里变成两个逻辑核心,从而同时执行两个线程。
我们常听到的"8 核 16 线程",指的正是通过这种硬件技术,让一个物理车间(核心)可以在同一时间塞进两个工人(线程)一起干活,从而把车间的设备利用率榨干,让一个核心模拟出两个逻辑核心的效果。
为了理解它是如何实现的,我们需要深入到 CPU 核心的内部结构中去。
5.1 核心内部的"分工":管理区 vs 干活区
要明白超线程的原理,首先得把一个 CPU 物理核心拆成两部分:
- 状态资源/前端管理(架构状态,Architecture State): 负责和操作系统对接,接收指令,记住当前程序运行到哪一步了(寄存器、程序计数器等)。
- 执行引擎/后端干活(Execution Engine): 真正动手做数学运算、逻辑判断的硬件单元(如 ALU 算术逻辑单元、FPU 浮点运算单元)。
在没有超线程的传统单线程核心里,管理区和干活区是 1:1 绑定的。
5.2 为什么要搞超线程?(物理核心的"偷懒"现象)
CPU 执行指令的速度极快,但人类写的代码往往很不高效。在传统核心中,当一个线程在运行时,经常会出现以下情况:
- 数据还没从内存运过来:CPU 干活区只能停工死等(产生缓存缺失/Cache Miss)。
- 指令类型单一:比如当前指令全是"整数运算",那么核心里负责"浮点运算"的硬件单元就在闲着抓耳挠腮。
据统计,传统单线程核心在处理任务时,其内部干活的执行单元平均有 30% ~ 50% 的时间是在闲置和浪费的。
5.3 硬件实现方案:复制"管理区",共享"干活区"
超线程技术的精妙之处就在于:它不舍得花大成本去复制昂贵的"干活区",而是以极低的硬件成本(约占核心面积的 5%),复制了一份"管理区"。
实现步骤如下:
- 复制架构状态(Architecture State): 核心内部现在有了两套独立的寄存器和程序计数器。在操作系统看来,它看到了两个完全独立的"逻辑处理器"(CPU 0 和 CPU 1)。
- 操作系统开始派活: 操作系统信以为真,同时把"线程 A"和"线程 B"发给了这两个逻辑核心。
- 前端交替/同时解码: 核心内部的管理区 1 拿着线程 A 的指令,管理区 2 拿着线程 B 的指令。
- 共享执行引擎(乱序执行): 关键来了!这两个线程的指令被同时送入同一个"干活区"。由于现代 CPU 具有"乱序执行(Out-of-Order Execution)"的能力,干活区会像个时间管理大师一样,只要发现有空闲的运算单元,就立刻把线程 A 或线程 B 的指令塞进去。
- 如果线程 A 因为等内存卡住了,干活区立刻全力全速去跑线程 B 的指令。
- 如果线程 A 在用整数单元,线程 B 在用浮点单元,它们就能在同一个核心里并行运转。
5.4 超线程的性能真相:它是 1+1=2 吗?
绝不是。 因为两个逻辑核心共享了同一个物理核心的算力上限(如执行单元、缓存、内存带宽)。
- 理想状态:如果两个线程需要的硬件资源刚好互补,超线程能带来 15% ~ 30% 的性能提升。
- 最坏状态(资源争抢):如果两个线程都是极度消耗同一种资源的"压榨型任务"(比如两个线程都在疯狂进行同一种科学计算),它们就会在核心内部大打出手,争夺同一个运算单元。此时,超线程不仅不会提速,反而可能因为频繁的切换和排队,导致性能略微下降(这也是为什么有些重度游戏玩家会选择在 BIOS 里关闭超线程)。
5.5 形象比喻
传统核心就像一个打字员(干活区)配一个经理(管理区)。经理看文件慢,打字员经常闲着。
超线程技术就是不增加打字员,而是再雇一个经理。现在有两个经理(逻辑核心)同时看不同的文件,并疯狂往同一个打字员(物理核心)手里塞稿子。只要打字员手速够快,或者两个经理给的文件类型不同,这个打字员的整体产出就能大大提升。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)