Skip to content

00 · 操作系统导读:一台机器内部在忙什么 ​

读完这篇,你要能回答一个问题:我写的一行代码,机器到底做了什么?

一句话本质 ​

操作系统是一层**"资源中介"**:它把一台机器的三种稀缺资源(CPU、内存、设备)切成小块,分给多个程序,并且保证它们不互相踩。

生活类比:一家餐厅 ​

操作系统餐厅
CPU灶台。只有一个(单核),谁抢到谁能炒
进程一桌客人的订单。有自己的食材、自己的进度、互不干扰
线程同一桌订单里的几道菜。共用一个操作台,但可以同时做
内存操作台。面积有限,摆不下就收进仓库
磁盘后厨仓库。很大,但取东西慢得多
调度器排号叫号的服务员
系统调用客人不能自己进后厨,只能叫服务员
缺页中断客人点了操作台上没有的菜,服务员去仓库取

这套类比贯穿整个模块。后面所有篇目都用这张表。

模块地图:5 篇怎么接 ​

+-- 用户态:你的程序
|     只能算数,只能访问自己的地址
|
|     (唯一合法入口:系统调用,见 05)
|           |
|           v
+-- 内核态:管理员
|     · 谁在用 CPU     -->  进程 / 线程     01
|     · 地址怎么翻译   -->  虚拟内存        02
|     · 谁能同时动     -->  锁 / 调度       03
|     · 怎么等设备     -->  IO 模型         04

五篇不是五个独立话题,是同一个内核的五个侧面。它们的接口关系:

  • 01 进程线程:定义了"谁"在跑。它是 02/03/04 的主体——内存是给进程的,锁是线程抢的,IO 是进程在等。
  • 02 虚拟内存:定义了"跑在哪"。它让 01 里的每个进程以为自己独占一台机器。
  • 03 调度同步:定义了"怎么分"。CPU 分给谁(调度)、内存里的共享数据谁先动(同步)。
  • 04 IO 模型:定义了"怎么等"。等设备的时候,CPU 不能干等着——这就把 01 的"阻塞/就绪"和 03 的"调度"接起来了。
  • 05 内核态:定义了"怎么进门"。前四篇的所有能力,用户程序都只能通过它来请求。

一条主线:程序跑起来发生了什么 ​

把五篇串起来,就是这一条线。建议你先通读一遍这条线,再回去看细节:

1. 你双击程序
   v  内核创建一个进程(01):分配 PID、地址空间、打开文件表
2. 进程被放进就绪队列
   v  调度器选中它(03),CPU 开始执行它的指令
3. 它要读一个变量
   v  CPU 拿到的是虚拟地址(02),查页表翻译成物理地址
   v  页表说"这页不在内存里"> 缺页中断 > 从磁盘换入
4. 它要读文件
   v  用户态不能直接碰磁盘 > 发起系统调用(05)
   v  内核把请求交给磁盘,进程进入阻塞态(01)
   v  调度器换别的进程上 CPU(03)—— 这就是"并发"的真相
5. 磁盘好了,中断把进程唤醒
   v  进程回到就绪队列,等下一次被调度
6. 两个线程要改同一个计数器
   v  用锁互斥(03),或者用 CAS 无锁

这条线里的每一步,都是一个高频面试题。学完五篇后回来重读,你会发现每一句都能展开讲三分钟。

学这个模块的方法 ​

  1. 别背概念,盯住"为什么"。每个机制的存在理由都是"不这么做会出什么事故"。
  2. 一定要动手看。ps aux、cat /proc/self/maps、ss -tan,看一次比读十遍强。
  3. 画图。进程状态图、地址翻译图、IO 模型对比图,这三张图必须能默画。

和其他模块的连接 ​

  • < 来自:无(这是最底层的一块,是其他三块的地基)
  • > 影响 分层模型与一次请求的一生:网络请求的收发,本质是进程在等 IO(04)+ 内核协议栈在处理
  • > 影响 复杂度与数组、链表:数组比链表快,根因是 CPU 缓存和内存布局,属于 02 的范畴
  • > 影响 事务与 ACID:数据库的 WAL 日志、刷盘、fsync,全部建立在 04 的 IO 模型上
  • > 影响 锁与死锁:数据库死锁和 OS 死锁是同一套理论

自测 3 问 ​

Q1:操作系统到底在管哪三样东西?为什么是这三样?

点开看答案

CPU、内存、设备(IO)。

因为这三样是稀缺且必须共享的:一台机器只有一个(或几个)CPU 核,内存容量有限,磁盘和网卡数量有限。而程序有很多个,每个都想独占。

如果资源无限,就不需要操作系统了——每个程序自己跑自己的就行。操作系统的全部存在理由,就是"资源不够,得排队分"。

Q2:为什么用户程序不能直接操作硬件?

点开看答案

两个原因:

  1. 会互相破坏。A 程序可以直接改磁盘的某个扇区,就能改掉 B 程序的数据,甚至改掉内核本身。
  2. 会死锁整个系统。直接操作硬件需要精细的时序和状态机,一个程序写错就可能让设备卡死,而它自己没有权限也没有能力恢复。

所以硬件被划了一条线:用户态只能算数,想碰硬件必须"申请"(系统调用),由内核检查权限后代为执行。这条线就是 05 篇讲的"特权级"。

Q3:如果一台机器只有一个 CPU 核,还能同时跑 100 个程序吗?怎么做到的?

点开看答案

能。这叫并发,不是并行。

做法是"快速轮换":每个程序跑几毫秒,时间片用完就被强制换下来,换下一个。因为切换速度(毫秒级)远快于人感知(百毫秒级),看起来就像同时在跑。

关键点:切换是有成本的(保存寄存器、切换页表、刷 TLB,即"上下文切换")。所以不是切得越勤越好——切太勤,时间全花在切换上了。这个权衡在 03 篇展开。

类比失效处 / 易错点 ​

  • "灶台只有一个"只对单核成立。多核是多个灶台,此时才有真正的"并行"。面试常在这里挖坑:并发 ≠ 并行。
  • "操作台"是连续的,内存不是。物理内存被切成固定大小的"页",一个进程的页可以散落在任意位置,靠页表拼起来。这是 02 篇的核心。
  • 餐厅里客人能看见后厨,程序看不见内核。用户态程序连内核的内存地址都访问不到(会触发段错误),这个隔离比餐厅严格得多。
  • "进程 = 一桌订单"这个类比会让人误以为进程之间能共享。实际上进程的地址空间是完全隔离的,共享必须显式申请(共享内存)。

✅ 验收清单 ​

  • 能说出操作系统管理的三种资源,并解释"为什么资源无限就不需要 OS"
  • 能用餐厅类比,把进程/线程/内存/磁盘/调度/系统调用六个词一次讲对
  • 能在纸上画出上面那张"5 篇怎么接"的图,并说出每篇之间的接口
  • 能不看资料口述"程序跑起来发生了什么"那条主线,至少说出 5 个步骤
  • 能解释并发和并行的区别,并说出上下文切换的代价
  • 合上书,用自己的话讲 3 分钟,中途不卡壳