1. 为什么操作系统术语总让人“中英文对照着看才明白”
做操作系统相关学习或者开发工作的人,多少都遇到过这种尴尬:翻开中文教材,每个字都认识,合在一起却不知道在说什么;转头去看英文文档或者源码注释,反而能猜出个大概。比如“进程”“线程”这种基础词还好,到了“上下文切换”“信号量”“页表”“中断向量”这种概念,中文译名和英文原词经常对不上号,不同教材的翻译还不统一,同一个英文术语能出现三四种中文说法。
我整理这份术语对照的初衷很简单:操作系统是计算机专业里最需要精确理解概念的领域之一,而概念的起点就是术语。很多初学者卡住,不是因为抽象思维不行,而是因为脑子里没有一个清晰的中英文映射表,导致读文档的时候要反复在两种语言之间切换,注意力全耗在查词上了。如果你正准备面试、准备考研或者刚看操作系统源码,这份对照清单能帮你少走很多弯路。
这篇是第一篇,聚焦操作系统最基础、最常用的几个板块:进程与线程、内存管理、文件系统、设备与I/O。每个术语我都会解释核心含义,并结合实际场景说明为什么这个术语重要、它在真实系统里是怎么运作的。有些词我会补充一些记忆技巧和易混淆点,这些都是我在学习和实际开发中踩过坑后总结出来的。
2. 进程与线程:操作系统的“执行单位”术语矩阵
2.1 进程相关核心名词
先看这一组最基础的对照关系:
| 英文术语 | 常见中文译名 | 一句话理解 |
|---|---|---|
| Process | 进程 | 正在运行的程序实例,操作系统分配资源的基本单位 |
| Thread | 线程 | 进程内的执行流,CPU调度的基本单位 |
| Process Control Block (PCB) | 进程控制块 | 记录进程所有信息的数据结构 |
| Process State | 进程状态 | 进程在不同阶段所处的状态(就绪、运行、阻塞等) |
| Ready Queue | 就绪队列 | 保存所有已准备就绪、等待CPU的进程队列 |
| Context Switch | 上下文切换 | 从一个进程切换到另一个进程时保存和恢复现场的过程 |
Process译成“进程”,很多人第一反应是把它当成程序。程序(Program)是静态的,就是磁盘上那堆文件;进程是动态的,是程序被加载到内存后运行起来的样子。同一个程序可以同时跑出多个进程,比如打开三个浏览器窗口,往往是三个渲染进程各管一个。PCB是关键中的关键,操作系统靠它管理所有进程,里面装了进程ID、状态、寄存器值、打开的文件列表、内存分配信息等等,可以把它理解成进程的“户口本”。
Context Switch是个高频考点,也是很多性能问题的根源。每次上下文切换,CPU要把当前进程的寄存器、程序计数器等现场保存到PCB里,再把下一个进程的现场从PCB恢复出来。这个操作本身不干活,纯粹是开销。如果一个系统频繁切换上下文,CPU的利用率就会明显下降,这就是为什么某些高并发场景下,减少线程切换比增加线程数更有效。
2.2 调度与同步的关键术语
| 英文术语 | 常见中文译名 | 一句话理解 |
|---|---|---|
| Scheduler | 调度器 | 决定下一个占用CPU的进程是谁的模块 |
| Preemptive Scheduling | 抢占式调度 | 系统能强行中断当前进程、把CPU让给更高优先级进程的调度方式 |
| Time Slice | 时间片 | 进程一次能占用CPU的最长时间 |
| Deadlock | 死锁 | 多个进程互相等待对方释放资源,导致谁都推进不了 |
| Semaphore | 信号量 | 用于控制多个进程对共享资源访问的计数器 |
| Mutex | 互斥锁 | 保证同一时刻只有一个进程能访问共享资源的锁 |
| Critical Section | 临界区 | 访问共享资源、不能被多个进程同时进入的代码段 |
| Race Condition | 竞态条件 | 多个进程同时读写共享数据,结果取决于执行顺序的异常情况 |
调度器是操作系统的“交通警察”,负责决定谁能用CPU、用多久。抢占式调度这个词里的“抢占”很形象:高优先级的进程来了,可以直接把CPU从当前进程手里抢过来。与之相对的是非抢占式调度,进程自觉跑完才让出CPU,这在多任务系统里很少见,因为一个进程死循环会导致整个系统卡死。时间片就是调度器给每个进程的“轮值时间”,到了时间片末端,调度器不管进程跑没跑完,先换人再说。
死锁和竞态条件是并发编程里最经典的两类问题。死锁的四个必要条件——互斥、持有并等待、不可剥夺、循环等待——不止面试要背,实际排查线上问题也会用到。竞态条件更隐蔽:代码每个语句执行得都很正常,但因为共享变量的写入顺序不确定,最终结果就飘忽不定。信号量和互斥锁的区别是初学者最容易混淆的:Mutex是“只能一个人进门的锁”,Semaphore则维护一个计数器,允许多个资源同时被使用,比如一个有10个坑位的停车场,车位数量就是信号量。
2.3 从面试视角看进程术语的考察方式
扩展开说,进程线程这块是操作系统面试的“第一关”。几乎必考的问题是进程和线程的区别,标准答法是:进程是资源分配的基本单位,线程是CPU调度的基本单位,同一个进程内的线程共享进程的地址空间和资源,线程切换比进程切换开销更小。如果再深入一点,面试官常追问线程上下文切换为什么比进程切换轻量——因为同一个进程内的线程切换不需要切换地址空间,内存映射相关的开销就省了。
另一个常见考察点是进程的几种状态:new(新建)、ready(就绪)、running(运行)、waiting(阻塞/等待)、terminated(终止)。很多教材画的是五状态图,实际Linux里的进程状态还要多一些,比如TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE对应可中断睡眠和不可中断睡眠。不可中断睡眠这个状态值得注意,它通常出现在进程等待I/O的时候,这时候用kill命令都杀不掉它,除非I/O操作返回或者系统重启。
3. 内存管理:把“内存”这个词拆开看
3.1 地址与虚拟内存术语
| 英文术语 | 常见中文译名 | 一句话理解 |
|---|---|---|
| Address Space | 地址空间 | 进程能访问的内存地址范围 |
| Virtual Memory | 虚拟内存 | 将物理内存与逻辑地址分离、扩展可用内存的机制 |
| MMU (Memory Management Unit) | 内存管理单元 | CPU内负责地址转换的硬件模块 |
| Address Translation | 地址转换 | 将虚拟地址映射为物理地址的过程 |
| Physical Address | 物理地址 | 实际内存硬件上的地址 |
| Logical Address | 逻辑地址 | 程序视角看到的地址,也称virtual address |
虚拟内存这个概念,很多人只在理论上理解,没意识到它就在每台电脑上跑着。你开很多软件,内存总容量加起来可能超过物理内存大小,系统照样能跑,靠的就是虚拟内存机制。每个进程看到一块连续的、私有的地址空间,这块地址空间由操作系统和MMU共同配合映射到真实的物理内存上,映射不了的部分就放到磁盘上的交换区(swap)里。
“进程看到的地址不是真实地址”——这句话是理解内存管理的钥匙。程序里打印出来的指针数值,是逻辑地址,不是物理地址。好处很明显:不同进程可以有相同的逻辑地址而不冲突;进程之间相互隔离,一个进程无法随意读写另一个进程的内存;还可以把不常用的数据淘汰到磁盘,腾出物理内存给更活跃的数据用。
3.2 分页与页表术语
| 英文术语 | 常见中文译名 | 一句话理解 |
|---|---|---|
| Paging | 分页 | 将内存和地址空间划分为固定大小块的机制 |
| Page | 页面/页帧 | 分页的基本单位,通常4KB大小 |
| Page Table | 页表 | 虚拟页到物理页帧的映射表 |
| TLB (Translation Lookaside Buffer) | 快表/转译后备缓冲 | 缓存页表项的高速缓存硬件 |
| Page Fault | 缺页中断/缺页异常 | 访问的页面不在物理内存,需要从磁盘调入 |
| Fragmentation | 碎片 | 内存空间被分割成大量不连续小块的浪费现象 |
| Thrashing | 颠簸/抖动 | 系统频繁换页导致CPU大量花在换页而非执行程序上 |
分页是虚拟内存最常见的实现方式。为什么固定大小而不是整块分配?因为整块分配会造成严重的碎片问题。想象一下去玩夹娃娃机,一堆娃娃大小不一,夹走几个后剩下的空隙都没法利用,磁盘文件分配也是类似道理。分页把内存切成整齐的4KB小格子,就像乐高积木一样,拼拼拆拆都方便很多。
Page Table是核心数据结构,每一个进程都有属于自己的页表。页表里记录某个虚拟页对应哪个物理页帧,有没有在内存中,访问权限是什么。页表本身也占用内存,32位系统下一个进程的页表可能就要占掉几MB,64位系统页表规模更夸张,所以后续出现了多级页表和倒排页表来缓解这个问题。TLB是页表的“缓存版”,原理和CPU缓存一样,把最近用过的地址转换结果存下来,避免每次访存都去查一遍页表。TLB命中率直接决定内存访问速度,命中率高时地址转换基本无开销,命中率低时性能会断崖式下跌。
Page Fault不是错误,是正常机制。程序访问的页面如果不在物理内存,MMU发现地址转换失败后触发缺页异常,操作系统负责把数据从磁盘读入内存,更新页表再让程序继续跑。一个程序刚启动时会有大量缺页,因为它的代码和数据都还没调入内存,这是正常的冷启动行为。但如果系统物理内存不够,刚换出的页面马上又被访问,再换出再缺页,CPU几乎都在处理换页操作,程序执行速度骤降,这就是Thrashing。我实际调优时遇到过类似现象:物理内存耗尽后系统响应越来越慢,硬盘灯常亮不灭,操作系统一直在做无意义的换页,最后只能靠增加内存或者限制并发进程数解决。
3.3 页面替换算法相关术语
| 英文术语 | 常见中文译名 | 一句话理解 |
|---|---|---|
| Replacement Algorithm | 页面置换算法 | 内存不足时决定淘汰哪个页面的算法 |
| FIFO (First In First Out) | 先进先出算法 | 最早进入的页面先被淘汰 |
| LRU (Least Recently Used) | 最近最少使用算法 | 淘汰最长时间没被访问的页面 |
| Optimal Algorithm | 最优算法 | 淘汰将来最长时间不被访问的页面(理论参考) |
| Working Set | 工作集 | 进程当前活跃访问的页面集合 |
页面置换算法是内存管理的精华内容。FIFO是最简单的,哪个页面进来得早先淘汰谁,但容易把频繁使用的页面也换出去。LRU是实际系统中用得最多的近似方案,思路是“如果一个页面最近没被访问,那它接下来也不太可能被访问”。这个直觉在很多场景下成立,但LRU的精确实现需要记录访问顺序,非常消耗硬件资源,所以实际系统往往用LRU的近似算法,比如给每个页面加一个访问位,定期清除、再次被访问就重新标记。
Optimal Algorithm是理论上完美的算法:预知未来,淘汰最久不用的页面。它不可能在真实系统里实现,但常被用来做性能对比的上限参考。工作集的概念也很实用:如果一个进程的工作集能完整放进物理内存,它就能高效运行;放不下就会颠簸。系统管理员常说的“内存不足导致性能差”,本质上是多个进程的工作集加起来超过了物理内存总容量。
4. 文件系统:数据持久化的术语清单
4.1 文件与目录相关术语
| 英文术语 | 常见中文译名 | 一句话理解 |
|---|---|---|
| File System | 文件系统 | 操作系统中管理文件存储和访问的子系统 |
| File | 文件 | 存储在持久介质上的数据集合 |
| Directory | 目录 | 文件的集合,构成存储结构的节点 |
| Inode | 索引节点 | 保存文件元数据(大小、权限、位置等)的数据结构 |
| File Descriptor | 文件描述符 | 应用程序访问文件时使用的整数句柄 |
| Path | 路径 | 从根目录或当前目录到目标文件的地址描述 |
| Extended File Attributes | 扩展属性 | 文件上附加的自定义元数据 |
文件系统的抽象价值常被低估。磁盘本身只提供“读写一批字节”的能力,文件系统在此之上建立了文件、目录、路径的层次结构,让用户和应用程序可以按名称访问数据,不必关心数据具体落在哪个磁道的哪个扇区。Inode值得多说几句:Unix/Linux系统里新建一个文件,实际上做了两件事——分配一个Inode保存文件的元数据,再把这个文件名和一个Inode号关联起来。Inode里存了文件的所有者、权限、大小、时间戳、数据块位置等。为什么“硬链接”能实现多个文件名指向同一份数据?因为不同的目录项指向同一个Inode号而已。
File Descriptor常被拿来和Inode对比,这俩不是一回事。Inode是文件系统层面的结构,File Descriptor是进程层面的整数编号。程序打开一个文件,操作系统就返回一个文件描述符,之后读写操作都靠这个描述符定位到内核中的文件对象,再由文件对象指向Inode。一个进程能打开的文件数量是有限的,用ulimit -n能看到这个限制,之前开发时遇到过文件描述符泄漏,日志文件一天比一天大,最后进程报错“too many open files”,排查半天发现是某个模块打开文件后没关闭。
4.2 存储与挂载相关术语
| 英文术语 | 常见中文译名 | 一句话理解 |
|---|---|---|
| Block | 块 | 文件系统读写数据的基本单位 |
| Sector | 扇区 | 磁盘硬件读写的最小单位 |
| Superblock | 超级块 | 记录文件系统全局信息(类型、容量、状态)的区块 |
| Mount | 挂载 | 将存储设备接入目录树、使其可访问的操作 |
| Journaling File System | 日志文件系统 | 记录操作日志以快速恢复一致性的文件系统 |
| RAID | 磁盘阵列 | 用多块磁盘组合提高性能和可靠性的技术 |
Block和Sector的关系也经常把人绕晕。Sector是硬件层面最小读写单位,传统磁盘是512字节,现代大容量盘多是4KB。Block是文件系统层面的逻辑概念,通常包含多个Sector。可以这么理解:Sector是盘子上的扇区,Block是文件系统在上面画的格子,一个格子装几个扇区。块大小影响存储效率和性能,块太小会造成大量元数据开销,块太大又会导致小文件浪费空间。
Superblock是文件系统的“大脑”,里面存着整个文件系统的类型、总块数、空闲块数量、Inode表起始位置等信息。文件系统卸载或崩溃时,如果Superblock损坏,整个文件系统都无法识别。所以很多文件系统会在不同位置存多份Superblock备份。Journaling File System的核心提升是把写操作的“意图”提前记录下来:先写日志,再做实际操作,系统崩溃后可以根据日志快速恢复一致性,避免长时间的文件扫描。常见文件系统里Ext4、XFS都用了日志机制,区别主要在于日志模式和性能权衡。
Mount这个词在Windows和Linux语境下理解不同。Windows用户理解的是“盘符”,C盘、D盘;Linux把所有存储设备统一挂到根目录树的不同目录节点上,比如挂载一个U盘到/mnt/usb之后,访问/mnt/usb就是访问U盘内容。挂载的本质是让文件系统之间建立连接,让用户可以跨设备无缝访问。
5. 设备管理与I/O:计算机如何和外部世界打交道
5.1 中断与DMA相关术语
| 英文术语 | 常见中文译名 | 一句话理解 |
|---|---|---|
| Interrupt | 中断 | 硬件或软件发起的、打断当前执行的信号机制 |
| Interrupt Handler | 中断处理程序 | 响应中断后执行的内核函数 |
| DMA (Direct Memory Access) | 直接内存访问 | 硬件设备绕过CPU直接读写内存的技术 |
| Polling | 轮询 | 不断主动检查设备状态的等待方式 |
| ISR (Interrupt Service Routine) | 中断服务例程 | 中断处理程序的具体实现体 |
中断是操作系统响应硬件事件的核心机制。没有中断的话,CPU只能不停轮询设备“数据好了吗?好了吗?”,浪费大量算力。有了中断,设备完成I/O操作后主动发一个信号,CPU被打断后转到对应的中断处理程序执行,处理完再回到原来的工作流。这和现实中的“预约叫号”很像:你不必一直在窗口前等着,叫到号时服务员会主动通知你。
Polling和中途的比较值得留意。轮询的成本是持续的CPU占用,但实现简单、延迟可预测;中断的成本是上下文切换和处理程序的开销,适合I/O频率低、事件稀疏的场景。很多高性能网络框架在高频小包场景下宁可轮询也不依赖中断,因为中断开销可能比处理数据本身还大。DMA则解决另一个痛点:传统PIO方式下,每次设备数据传输都要CPU全程搬运,从设备到寄存器再到内存,4KB数据要中断几千次。DMA允许设备控制器直接和内存交互数据,整块数据传完再中断CPU一次,CPU只在开头设定传输参数、结尾处理结果,中间完全不用管。
5.2 缓冲与性能指标术语
| 英文术语 | 常见中文译名 | 一句话理解 |
|---|---|---|
| Buffer | 缓冲区 | 暂存数据以匹配不同速度设备的内存区域 |
| Cache | 缓存 | 存储经常访问数据的快速存储层 |
| Spooling | 假脱机 | 使用磁盘缓冲外部设备输入输出的技术 |
| Throughput | 吞吐量 | 单位时间内处理的请求量或数据量 |
| Latency | 延迟 | 从发出请求到得到响应的等待时间 |
| IOPS | 每秒输入输出操作次数 | 衡量存储设备随机读写性能的指标 |
Buffer和Cache在中文里常被都叫“缓存”,其实有区别。Cache的核心思路是“复用”:把读过的数据留着,下次再读直接命中。Buffer的核心思路是“缓冲”:协调上下游速度不一致,生产者快、消费者慢的时候,先把数据放在中间暂存区,防止生产者和消费者互相等待。典型例子是视频播放:网络下载快、播放器解码慢,下载的数据先填缓冲区,缓冲区有数据才播放。你可以理解为:Cache让你少干活,Buffer让你干活更平滑。
Spooling是个老概念,现在的打印系统还在用。打印机的速度远比CPU慢,程序不可能一直等着打印机慢慢打,于是打印任务先送到磁盘上的队列里,由后台进程按顺序取出来交给打印机。这样同一时刻多个程序提交打印任务也不会冲突。Throughput和Latency是衡量任何子系统都绕不开的两个指标:吞吐量是“单位时间能干多少活”,延迟是“一件事从开始到结束要等多久”。高吞吐不一定低延迟,低延迟也不一定高吞吐,很多系统设计就是在两者之间做权衡。对数据库来说,IOPS和延迟是同行口中常提的指标,一次SSD随机读延迟在几十微秒级别,顺序读吞吐能到几GB每秒,实际选型时心里要有一笔账。
6. 学操作系统术语的几个实操技巧
先说说我自己积累的学习方法。第一,术语不要死记硬背,一定要放到“场景”里去理解。比如我把Page Fault记成“程序访问了一个不在物理内存的页面”,接着问自己:为什么不在物理内存?因为可能被换出去了。换出去带来了什么设计动机?为了给更重要的页面腾地方。这个“为什么”链条拉下来,一个术语就变成了一段知识,不再是一个孤立单词。学习Inode的时候同理,理解“文件名是目录项里的记录,Inode才是文件本体”,比背十遍“Inode是索引节点”管用得多。
第二,做题和动手验证是强化记忆最快的方式。看十遍进程状态图,不如用脚本模拟一个死等I/O的进程,再观察它的状态;背十遍页表结构,不如打开一个程序的/proc目录看内存映射。Linux系统里有很多现成的工具可以观察术语对应的真实系统行为,比如用ps看进程状态、用free看内存分布、用dd测磁盘吞吐。理论联系实际之后,术语从“书上的名次”变成了“我亲眼看到的现象”,印象自然牢固。
第三,注意中英文术语之间偶尔存在“同词不同义”的坑。英文原词在操作系统领域和通用领域含义不同,比如“Address”在日常是地址,操作系统里是地址空间的地址;“Cache”作为名词是一回事,作为动词“缓存数据”是另一回事。遇到含糊的地方,多去核对官方文档的上下文,不要只看对照表就觉得自己懂了。
这篇整理的是基础部分。操作系统领域还有其他重要术语板块,比如进程间通信的管道(Pipe)、消息队列(Message Queue),网络相关的套接字(Socket),Linux内核特有的进程模型术语等等。这些内容更多、关联性更强,一篇无论如何装不下,后续再分篇梳理。做这份对照的过程中,我最大的感受是:操作系统这门学科很像拼图,术语是一块一块的碎片,光记住碎片没有用,得知道它们之间怎么拼接,整个系统的运转逻辑才会慢慢显影出来。希望这份对照能帮你把第一块碎片拼上。