欢迎光临
我们一直在努力

操作系统八股文:进程与线程全面梳理(附调度算法+IPC+锁机制)

文章目录

    • 前言
    • 一、用户态和内核态
    • 二、进程和线程
      • 2.1 本质区别
      • 2.2 为什么要有线程
      • 2.3 进程、线程、协程对比
      • 2.4 多线程的优劣
    • 三、进程的五种状态
    • 四、进程上下文切换
      • 4.1 进程上下文有哪些
      • 4.2 切换流程
      • 4.3 进程切换 vs 线程切换
    • 五、线程切换详细过程
    • 六、三级调度
    • 七、进程调度算法
      • 7.1 先来先服务(FCFS)
      • 7.2 最短作业优先(SJF)
      • 7.3 高响应比优先(HRRN)
      • 7.4 时间片轮转(RR)
      • 7.5 最高优先级(HPF)
    • 八、进程间通信(IPC)
      • 8.1 六种方式对比
    • 九、线程间通信与同步
      • 互斥锁 vs 自旋锁
    • 十、总结

前言

这篇文章把进程、线程相关的操作系统八股文全部梳理一遍,面试前看一遍基本够用。

从基础概念到调度算法,从上下文切换到进程通信,覆盖高频考点,每个知识点都给出了面试官最想听到的角度。


一、用户态和内核态

本质区别是 CPU 的执行权限不同。

内核态下 CPU 可以执行所有指令,访问所有硬件资源;用户态下只能执行部分指令集,无法直接操作硬件。

为什么要这么设计?三个原因:

  • 安全性:用户程序无法直接破坏硬件资源
  • 稳定性:用户态程序崩溃不会拖垮整个系统
  • 隔离性:内核和用户程序之间有明确边界,便于维护

内核态的核心操作:内存管理、进程管理、设备驱动、系统调用。


二、进程和线程

2.1 本质区别

维度进程线程
定义 资源分配的基本单位 任务调度和执行的基本单位
地址空间 独立 共享所属进程的地址空间
切换开销 大(需切换地址空间) 小(只切换栈和寄存器)
崩溃影响 子进程崩溃不影响其他进程 线程崩溃可能导致整个进程崩溃
通信方式 管道、消息队列、共享内存等 直接读写共享内存

2.2 为什么要有线程

用视频播放器举例。播放器有三个核心模块:读取数据、解压缩、播放画面。

单进程串行执行,读取卡住了,后面全卡死,画面不连贯。

多进程方式解决了并发问题,但进程间通信复杂,切换开销大。

线程的出现解决了这个矛盾:并发执行 + 共享地址空间,通信效率高,切换开销小。

2.3 进程、线程、协程对比

进程
├── 独立内存空间、独立堆栈
├── 内核调度
├── 切换开销:最大(需切换页表、TLB 刷新)
└── 隔离性最强

线程
├── 共享进程的堆和全局变量,独立栈
├── 内核调度
├── 切换开销:中等(只切换栈+寄存器)
└── 存在数据竞争问题,需要同步机制

协程
├── 共享堆,独立寄存器上下文和栈
├── 用户态调度,不需要内核参与
├── 切换开销:最小(无内核态切换)
└── 需要程序员显式管理调度

2.4 多线程的优劣

优势:充分利用多核 CPU,多任务并发,提高吞吐量。

劣势:

  • 数据竞争,需要加锁,锁本身有开销
  • 有死锁风险
  • 消耗更多内存(每个线程都有自己的栈)

线程是不是越多越好?

不是。线程过多会导致:

  • 频繁上下文切换,CPU 时间大量浪费在切换上
  • 内存占用上升
  • 锁竞争加剧,死锁概率增大

  • 三、进程的五种状态

    ┌─────────────────────────────────┐
    ▼ │
    NULL ──► 创建态 ──► 就绪态 ◄──────────────── 运行态 ──► 终止态
    │ 时间片用完 / 被抢占 │
    │ 调度器选中 │
    ▼ ▼
    运行态 ──────────────────────► 阻塞态
    等待 I/O 等事件

    事件完成 │
    就绪态 ◄──────────────────────┘

    关键转换:

    • 阻塞态 → 运行态:不能直接转换,必须先回到就绪态,再被调度器选中
    • 就绪态 → 阻塞态:不能转换,没在运行,无法发起等待

    四、进程上下文切换

    4.1 进程上下文有哪些

    分三个层次:

    用户级上下文

    • 代码段、数据段、堆、用户栈(用户空间的内存内容)

    寄存器上下文

    • PC(程序计数器):下一条指令地址
    • SP(栈指针):当前栈顶
    • PSW(程序状态字):标志位,零标志/进位标志/特权位等
    • 通用寄存器:运算中间结果、函数参数、返回值

    系统级上下文

    • PCB 本身(进程状态、PID、优先级)
    • 页表(内存映射)
    • 文件描述符表
    • 内核栈

    寄存器上下文保存在 PCB(进程控制块)中,PCB 存在内核内存里,用户态无法直接访问。

    4.2 切换流程

    进程 A 运行

    ▼ 触发切换(时间片用完 / 系统调用 / I/O 阻塞)

    ├── 1. 保存 A 的寄存器上下文 → A 的 PCB
    ├── 2. A 的状态改为就绪或阻塞
    ├── 3. 调度器从就绪队列选出进程 B
    ├── 4. 从 B 的 PCB 恢复寄存器上下文
    └── 5. 切换地址空间(换页表,TLB 刷新)


    进程 B 运行

    4.3 进程切换 vs 线程切换

    操作进程切换线程切换(同进程内)
    地址空间 需要切换(刷 TLB) 不需要(共享)
    寄存器 保存/恢复 保存/恢复
    内核栈 切换 切换
    总开销

    线程切换快,本质上节省的是地址空间切换的代价(页表切换 + TLB 失效)。


    五、线程切换详细过程

    线程 A 运行

    ▼ 调度器介入

    ├── 1. 保存 A 的 CPU 上下文 → A 的 TCB(线程控制块)
    │ 包括:PC、SP、PSW、通用寄存器
    ├── 2. A 的状态 Running → Ready 或 Blocked
    ├── 3. 调度器按算法选出线程 B
    ├── 4. 从 B 的 TCB 恢复上下文
    └── 5. 跳转到 B 的 PC 指向的位置继续执行


    线程 B 继续运行

    上下文保存在 TCB(线程控制块)中,TCB 是 OS 管理线程的数据结构,存在内核内存里。


    六、三级调度

    调度层级别名调度对象频率
    长程调度 作业调度 作业 低(从后备队列选作业进内存)
    中程调度 内存调度 进程 中(换入/换出内存)
    短程调度 CPU 调度 进程(现代OS是线程) 极高(毫秒级)

    注意:长程调度的对象是作业,不是进程。作业经过长程调度才创建进程进入内存。


    七、进程调度算法

    7.1 先来先服务(FCFS)

    按进入就绪队列的顺序调度,非抢占式。

    • 优点:实现简单,公平
    • 缺点:长作业先来,短作业等待时间过长

    适合 CPU 繁忙型,不适合 I/O 繁忙型。

    7.2 最短作业优先(SJF)

    优先选运行时间最短的进程。

    • 优点:提高系统吞吐量
    • 缺点:长作业可能永远饿死

    7.3 高响应比优先(HRRN)

    响应比 = (等待时间 + 要求服务时间) / 要求服务时间

    等待越久,响应比越高,兼顾了长作业和短作业,是 FCFS 和 SJF 的折中。

    7.4 时间片轮转(RR)

    每个进程分配固定时间片,用完就切换,循环执行。

    时间片太短 → 切换频繁,CPU 效率低 时间片太长 → 短作业响应慢 通常设为 20ms~50ms。

    7.5 最高优先级(HPF)

    选就绪队列中优先级最高的进程运行。

    • 静态优先级:创建时确定,不变
    • 动态优先级:随等待时间增加而提升(避免饿死)
    • 非抢占式 / 抢占式两种处理方式

    缺点:低优先级进程可能永远得不到执行。


    八、进程间通信(IPC)

    8.1 六种方式对比

    管道(Pipe)
    ├── 匿名管道:只能用于父子/兄弟进程,单向,内核缓存
    └── 命名管道:突破亲缘限制,基于文件系统

    消息队列
    └── 内核中的消息链表,支持自定义数据类型,有用户态/内核态拷贝开销

    共享内存(最快)
    └── 直接映射到相同物理内存,零拷贝,但需要配合信号量防竞争

    信号量
    └── 计数器,P操作(-1)可阻塞,V操作(+1)可唤醒,解决互斥/同步

    信号
    └── 异步通知机制,SIGKILL/SIGSTOP 无法被捕捉或忽略

    Socket
    └── 跨主机通信,也支持本地通信,TCP/UDP/Unix域套接字

    信号 vs 信号量(高频混淆点):

    信号信号量
    用途 异步事件通知 资源计数,同步互斥
    本质 软件中断 计数器
    场景 Kill 进程、Ctrl+C 控制并发访问数量

    共享内存为什么最快?

    共享内存把同一块物理内存映射到多个进程的虚拟地址空间,进程直接读写,无需拷贝,不需要陷入内核。


    九、线程间通信与同步

    Linux 提供五种机制:

    机制核心用途等待方式
    互斥锁 保护临界区,互斥访问 阻塞睡眠
    自旋锁 临界区极短的互斥场景 忙等(CAS 原子指令)
    读写锁 读多写少的共享资源 读并发,写独占
    条件变量 等待某个条件成立(配合互斥锁) 阻塞睡眠
    信号量 控制资源访问数量 P操作可阻塞,V操作唤醒

    互斥锁 vs 自旋锁

    两者目的相同:都是保护共享资源,区别只在于抢不到锁时怎么等。

    互斥锁:抢不到就睡觉,让出 CPU(适合锁持有时间长的场景) 自旋锁:抢不到就原地转圈,继续占着 CPU(适合锁持有时间极短的场景)

    单核 CPU 不要用自旋锁——持有锁的线程没机会运行,自旋线程会一直空转。


    十、总结

    面试高频考点速记

    进程 vs 线程:资源分配 vs 调度执行,切换开销不同
    五种状态:阻塞→就绪→运行,不能跳步
    上下文切换:保存寄存器→换状态→调度→恢复→执行
    三级调度:长程=作业,中程=换入换出,短程=CPU调度
    进程通信:共享内存最快,管道最简单,Socket跨主机
    线程同步:互斥锁睡眠等,自旋锁忙等,读写锁读并发写独占


    赞(0)
    未经允许不得转载:171主机测评 » 操作系统八股文:进程与线程全面梳理(附调度算法+IPC+锁机制)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址