软件设计师考点详解:操作系统知识(进程、内存、文件系统)

操作系统是软件设计师考试的重点章节之一,约占上午题的10%。这部分内容理论性强,概念较多,但掌握了核心原理后会发现其实很有规律。本文将系统梳理操作系统的核心知识点。

一、进程管理

进程与线程概念

进程定义

  • 程序的一次执行过程
  • 系统进行资源分配和调度的基本单位
  • 拥有独立的地址空间和系统资源

线程定义

  • 进程内的一个执行单元
  • CPU调度和分派的基本单位
  • 共享进程的地址空间和资源

进程 vs 线程对比

特性 进程 线程
地址空间 独立 共享
资源开销
切换开销
通信方式 IPC机制 直接共享
稳定性 相对独立 相互影响

进程状态与转换

五态模型

  • 新建态:进程刚被创建,尚未进入就绪队列
  • 就绪态:进程已准备好,等待CPU调度
  • 运行态:进程正在CPU上执行
  • 阻塞态:进程等待某事件发生(如I/O完成)
  • 终止态:进程执行完毕或被强制终止

状态转换

  • 就绪 → 运行:被调度程序选中
  • 运行 → 就绪:时间片用完或被更高优先级进程抢占
  • 运行 → 阻塞:等待I/O或其他事件
  • 阻塞 → 就绪:等待的事件发生

进程同步与互斥

临界资源:一次只允许一个进程使用的资源
临界区:访问临界资源的代码段

同步机制要求

  • 互斥条件:任何时候最多一个进程在临界区
  • 进步条件:如果没有进程在临界区,应能立即进入
  • 有限等待:进程等待进入临界区的时间应有限

经典同步问题

生产者-消费者问题

  • 共享缓冲区,生产者放入产品,消费者取出产品
  • 需要两个信号量:empty(空缓冲区数量)、full(满缓冲区数量)
  • 还需要mutex信号量保证对缓冲区的互斥访问

读者-写者问题

  • 多个读者可同时读,但写者必须独占
  • 通常优先考虑读者(读者优先)或写者(写者优先)

哲学家进餐问题

  • 5个哲学家,5根筷子,每人需要2根才能吃饭
  • 容易产生死锁,解决方案包括:
    • 限制同时进餐人数≤4
    • 规定拿筷子顺序(先拿编号小的)
    • 使用服务生协调

进程调度算法

调度类型

  • 高级调度(作业调度):决定哪些作业进入内存
  • 中级调度(内存调度):决定哪些进程挂起/激活
  • 低级调度(进程调度):决定哪个就绪进程获得CPU

常见调度算法

先来先服务(FCFS)

  • 按到达顺序调度
  • 优点:简单公平
  • 缺点:平均等待时间长,不利于短作业

短作业优先(SJF)

  • 优先调度预计运行时间短的作业
  • 优点:平均等待时间最短
  • 缺点:需要预知作业时间,可能导致长作业饥饿

高响应比优先(HRRN)

  • 响应比 = (等待时间 + 服务时间) / 服务时间
  • 兼顾等待时间和作业长度
  • 避免长作业饥饿

时间片轮转(RR)

  • 每个进程分配固定时间片
  • 时间片用完则切换到下一个进程
  • 优点:响应快,适合交互式系统
  • 缺点:时间片选择影响性能

多级反馈队列(MLFQ)

  • 多个优先级队列,不同队列不同时间片
  • 新进程进入最高优先级队列
  • 时间片用完则降级到下一级队列
  • I/O密集型进程保持较高优先级

二、内存管理

内存分配方式

连续分配

  • 单一连续分配:内存分为系统区和用户区
  • 固定分区分配:内存划分为固定大小的分区
    • 内部碎片:分区未完全利用的空间
  • 动态分区分配:根据进程大小动态划分
    • 外部碎片:分散的小空闲块无法利用

离散分配

  • 分页存储:内存和进程都划分为固定大小的页/块
  • 分段存储:按逻辑模块划分,段长可变
  • 段页式存储:先分段再分页

页面置换算法

最佳置换算法(OPT)

  • 替换以后永不使用或最长时间不使用的页面
  • 理论最优,但无法实现(需要预知未来)

先进先出算法(FIFO)

  • 替换最早进入内存的页面
  • 实现简单,但可能出现Belady异常(分配更多页框反而缺页率增加)

最近最少使用算法(LRU)

  • 替换最近最久未使用的页面
  • 性能接近OPT,但硬件实现复杂

时钟置换算法(Clock)

  • LRU的近似实现
  • 使用访问位,循环检查页面
  • 实现简单,性能较好

抖动(Thrashing)问题

产生原因

  • 进程分配的页框太少
  • 频繁的页面调入调出
  • CPU利用率急剧下降

解决方法

  • 工作集模型:为进程分配其工作集大小的页框
  • 页面错误频率(PFF):根据缺页率动态调整页框数

三、文件系统

文件逻辑结构

无结构文件(流式文件)

  • 字节序列,无内部结构
  • 如:源程序文件、可执行文件

有结构文件(记录式文件)

  • 由若干记录组成
  • 如:数据库文件、表格文件

文件物理结构

连续分配

  • 文件占用连续的磁盘块
  • 优点:支持顺序和随机访问,效率高
  • 缺点:容易产生外部碎片,文件扩展困难

链接分配

  • 每个块包含指向下一个块的指针
  • 隐式链接:指针在块内
  • 显式链接:指针集中在FAT表中
  • 优点:无外部碎片,易于扩展
  • 缺点:不支持随机访问,可靠性差

索引分配

  • 为每个文件建立索引块,记录所有数据块地址
  • 单级索引:直接索引
  • 多级索引:索引的索引(二级、三级索引)
  • 混合索引:直接索引 + 一级索引 + 二级索引 + 三级索引
  • 优点:支持随机访问,无外部碎片
  • 缺点:索引块占用额外空间

目录结构

单级目录

  • 所有文件在同一目录
  • 简单但无法重名,不适合多用户

两级目录

  • 主目录 + 用户子目录
  • 解决重名问题,但用户间无法共享

树形目录

  • 层次结构,路径名唯一标识文件
  • 支持重名和共享(通过链接)

无环图目录

  • 允许文件有多个父目录(硬链接、软链接)
  • 更灵活的共享机制

文件共享与保护

共享方式

  • 硬链接:多个目录项指向同一索引节点
  • 软链接(符号链接):创建指向目标文件路径的新文件

保护机制

  • 访问控制列表(ACL):为每个文件维护可访问用户列表
  • 访问控制矩阵:行表示用户,列表示文件
  • UNIX权限模式:用户/组/其他 + 读/写/执行权限

四、设备管理

I/O控制方式

程序直接控制

  • CPU直接控制I/O操作
  • 效率低,适用于简单设备

中断驱动

  • I/O完成后产生中断
  • 提高CPU利用率

DMA(直接内存访问)

  • DMA控制器直接管理数据传输
  • 适用于大数据量传输

通道控制

  • 专用处理器执行I/O指令
  • 适用于大型系统

缓冲技术

单缓冲

  • 一个缓冲区,CPU和I/O设备交替使用

双缓冲

  • 两个缓冲区,可并行处理

循环缓冲

  • 多个缓冲区组成环形队列
  • 适用于生产者-消费者模型

缓冲池

  • 统一管理多个缓冲区
  • 提高缓冲区利用率

设备分配与调度

独占设备:一次只能被一个进程使用(如打印机)
共享设备:可被多个进程同时使用(如磁盘)

SPOOLing技术

  • 将独占设备改造为共享设备
  • 利用磁盘作为缓冲区
  • 典型应用:假脱机打印

五、死锁处理

死锁必要条件

四个必要条件(同时满足才会死锁):

  1. 互斥条件:资源一次只能被一个进程使用
  2. 请求和保持条件:进程持有资源的同时请求新资源
  3. 不剥夺条件:已分配的资源不能被强制收回
  4. 循环等待条件:存在进程资源的循环等待链

死锁处理策略

预防死锁:破坏四个必要条件之一

  • 破坏互斥:一般不可行(资源本身特性)
  • 破坏请求和保持:一次性申请所有资源
  • 破坏不剥夺:允许抢占资源
  • 破坏循环等待:资源有序分配

避免死锁:动态检测是否安全

  • 银行家算法:检查资源分配是否会导致不安全状态
  • 需要知道进程的最大资源需求

检测与恢复

  • 死锁检测:定期检查系统是否存在死锁
  • 死锁恢复
    • 终止进程(全部或部分)
    • 资源抢占(回滚到安全状态)

忽略死锁

  • 某些系统选择不处理死锁(如UNIX)
  • 依赖应用程序正确设计

六、常考题型与解题技巧

进程调度计算题

典型问题

  • 计算各种调度算法的平均等待时间、周转时间
  • 分析调度顺序

解题技巧

  • 画甘特图辅助分析
  • 注意区分到达时间、服务时间、完成时间

页面置换计算题

典型问题

  • 给定页面访问序列,计算缺页次数
  • 比较不同算法的性能

解题技巧

  • 按访问顺序逐步模拟
  • 注意FIFO可能出现的Belady异常

死锁判断题

典型问题

  • 判断系统是否处于死锁状态
  • 应用银行家算法判断安全性

解题技巧

  • 构建资源分配图
  • 寻找环路判断死锁
  • 银行家算法要逐步尝试分配

文件系统计算题

典型问题

  • 计算文件最大长度
  • 分析索引结构的寻址能力

解题技巧

  • 理解各级索引的寻址范围
  • 注意块大小和地址长度的关系

七、学习建议

重点掌握内容

  1. 进程状态转换:理解各种状态间的转换条件
  2. 同步机制:掌握信号量的使用和经典同步问题
  3. 调度算法:能够计算各种算法的性能指标
  4. 内存管理:理解分页、分段的工作原理
  5. 死锁处理:掌握四个必要条件和处理策略
  6. 文件系统:理解各种物理结构的特点和适用场景

学习方法

  • 画图理解:进程状态图、资源分配图、文件结构图等
  • 对比记忆:各种调度算法、内存分配方式的对比
  • 实际联系:结合现代操作系统的实际实现来理解理论
  • 动手练习:通过真题练习巩固知识点

经验分享:操作系统的内容虽然抽象,但很多概念在日常编程中都会遇到。比如多线程编程中的同步问题、内存泄漏问题等,理解操作系统原理有助于写出更好的程序。


下一篇将讲解程序设计语言与编译原理的基础知识。