第四章 操作系统基础:进程与线程、调度算法、死锁与内存管理
操作系统是计算机系统中连接硬件与应用程序的核心系统软件,它负责管理计算机的处理器、内存、设备与文件等资源。对于军队文职计算机岗位的应试者而言,理解操作系统的基本原理不仅是笔试考核的重点,更是后续从事信息化装备运维、系统部署与故障排查的必备基础。本章围绕进程与线程、进程调度算法、死锁条件与处理、内存管理四大核心模块展开,结合军队信息化系统中常见的嵌入式终端、服务器集群及国产化操作系统(如麒麟、统信UOS)应用场景,帮助考生建立从理论到实践的完整认知框架。
4.1 进程与线程:并发执行的基本单位
4.1.1 核心原理:进程的组成与状态模型
进程是程序在某个数据集合上的一次执行过程,是操作系统进行资源分配和调度的基本单位。每个进程在内核中对应一个进程控制块(PCB),PCB 记录了进程标识符(PID)、程序计数器、寄存器状态、内存分配信息、打开文件列表及调度参数等关键数据。当操作系统进行进程切换时,需要保存当前进程的上下文(CPU 寄存器值、程序计数器、栈指针等),并恢复目标进程的上下文,这一过程称为上下文切换,其开销直接影响系统并发性能。
进程在其生命周期内会经历三种基本状态:就绪态(已具备运行条件,等待 CPU)、运行态(正在占用 CPU 执行指令)、阻塞态(因等待 I/O 或事件而暂时无法执行)。状态转换由调度器与事件驱动,例如:进程等待磁盘读取时从运行态转为阻塞态,I/O 完成后由阻塞态转为就绪态。
4.1.2 线程与进程的对比
线程是进程内部的一条执行路径,是 CPU 调度的基本单位。同一进程中的多个线程共享进程的地址空间、全局变量和打开文件,但各自拥有独立的栈和寄存器上下文。线程的创建与切换开销远小于进程,因此适合高并发、I/O 密集型的应用场景。下表从多个维度对比进程与线程:
| 对比维度 | 进程 | 线程 |
|---|---|---|
| 资源拥有权 | 独立地址空间、独立资源 | 共享所属进程的地址空间与资源 |
| 系统开销 | 创建/切换开销大 | 创建/切换开销小 |
| 通信方式 | IPC(管道、消息队列、共享内存) | 直接读写共享变量(需同步机制) |
| 健壮性 | 进程间相互隔离,一个崩溃不影响其他 | 一个线程崩溃可能导致整个进程退出 |
| 适用场景 | 多任务隔离、安全要求高的场景 | 高并发、I/O 密集、多核并行计算 |
4.1.3 实战场景:国产化终端上的多线程日志采集
在某部队信息系统的国产化终端(麒麟操作系统)上,需要同时采集网络流量、磁盘 I/O 和应用程序日志。若采用多进程模型,每个采集任务独立进程,虽然隔离性好,但频繁创建进程会消耗大量系统资源,且进程间数据汇总需要复杂的 IPC 机制。实际方案采用单进程多线程模型:主线程负责配置管理与数据汇总,三个工作线程分别执行流量抓取、磁盘监控和日志解析。线程间通过环形缓冲区传递数据,并使用互斥锁(pthread_mutex)保护共享队列。该方案将 CPU 占用率控制在 15% 以内,数据采集延迟低于 200ms,充分体现了线程在轻量级并发中的优势。
4.1.4 常见误区与复盘
- 误区一:认为线程越多性能越好。实际上,线程过多会导致上下文切换开销剧增,且共享资源的竞争加剧,性能反而下降。
- 误区二:混淆进程与程序的联系。程序是静态的指令集合,进程是动态的执行过程;同一程序可对应多个进程。
- 误区三:忽略线程安全问题。在信号处理或中断处理函数中访问共享变量,可能导致死锁或数据不一致。
4.2 进程调度算法:决定系统响应速度的关键
4.2.1 核心原理:调度算法的评价指标
进程调度算法决定哪个就绪进程获得 CPU 使用权。评价调度算法优劣的核心指标包括:CPU 利用率(CPU 忙碌时间占比)、吞吐量(单位时间内完成的进程数)、周转时间(进程从提交到完成的总时间)、等待时间(进程在就绪队列中等待的总时间)以及响应时间(从提交到首次产生响应的时间)。不同应用场景对指标侧重不同:批处理系统追求高吞吐量,交互式系统追求低响应时间。
4.2.2 典型调度算法对比
| 算法名称 | 调度方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 先来先服务(FCFS) | 非抢占 | 实现简单、公平 | 平均等待时间长,可能产生护航效应 | 批处理系统 |
| 短作业优先(SJF) | 非抢占/抢占 | 平均周转时间最短 | 长作业可能饥饿 | 批处理系统(需预估运行时间) |
| 优先级调度 | 抢占/非抢占 | 可区分紧急程度 | 低优先级进程可能饥饿 | 实时系统、军事指挥系统 |
| 时间片轮转(RR) | 抢占 | 响应时间短、公平 | 时间片大小影响性能 | 分时系统、交互式系统 |
| 多级反馈队列 | 抢占 | 兼顾响应与吞吐 | 参数配置复杂 | 通用操作系统(如 Linux) |
4.2.3 案例拆解:某指挥调度系统的优先级调度设计
在某战区联合作战指挥信息系统中,服务器需要同时处理三类任务:实时态势数据刷新(周期 50ms)、作战指令下发(偶发但紧急)、历史数据统计分析(后台任务)。若采用时间片轮转,紧急指令可能被延迟;若采用 SJF,长任务可能饥饿。最终设计采用抢占式优先级调度:实时态势刷新设为最高优先级(优先级 0),作战指令设为次高优先级(优先级 1),统计分析设为最低优先级(优先级 2)。同时引入优先级老化机制——每等待 10 秒,低优先级任务的优先级自动提升一级,避免饥饿。实测系统在峰值负载下,作战指令的响应时间从平均 120ms 降至 15ms,满足作战时效要求。
4.2.4 常见误区与复盘
- 误区一:认为 SJF 总是最优。SJF 需要预知进程运行时间,实际系统中难以精确预估,且长作业可能长期得不到调度。
- 误区二:忽略时间片大小的选择。时间片过小导致频繁上下文切换,过大则退化为 FCFS。通常取 10ms~100ms 之间,并考虑进程切换开销。
- 误区三:在实时系统中使用 FCFS 或 RR。实时任务必须使用优先级调度或速率单调调度(RMS)等实时算法。
4.3 死锁条件与处理:系统稳定性的底线
4.3.1 核心原理:死锁产生的四个必要条件
死锁是指多个进程因竞争资源而造成的一种僵局,若无外力作用,这些进程将永远无法继续推进。产生死锁必须同时满足以下四个条件:
- 互斥条件:资源在同一时刻只能被一个进程占用。
- 持有并等待条件:进程已持有至少一个资源,又在等待获取其他进程占用的资源。
- 不可剥夺条件:进程已获得的资源在未使用完之前不能被强行剥夺。
- 循环等待条件:存在一个进程等待环路,如 P0 等待 P1 的资源,P1 等待 P2 的资源,P2 等待 P0 的资源。
4.3.2 死锁处理策略
| 策略 | 核心思想 | 典型方法 | 优缺点 |
|---|---|---|---|
| 死锁预防 | 破坏四个必要条件之一 | 资源一次性分配(破坏持有并等待)、资源可剥夺(破坏不可剥夺)、资源有序分配(破坏循环等待) | 简单但资源利用率低 |
| 死锁避免 | 在资源分配前判断是否安全 | 银行家算法 | 需要预知最大需求,实现复杂 |
| 死锁检测与解除 | 允许死锁发生,定期检测并解除 | 资源分配图检测、进程回退/终止 | 检测周期影响性能,解除代价大 |
4.3.3 案例拆解:数据库并发访问中的死锁检测
某军队院校的学员信息管理系统采用 MySQL 数据库,在选课高峰期出现大量事务超时。通过 SHOW ENGINE INNODB STATUS 查看死锁日志,发现两个事务分别持有 A 表行锁并等待 B 表行锁,形成循环等待。DBA 的处置流程如下:
- 定位死锁事务:通过日志获取事务 ID 与涉及的 SQL 语句。
- 分析加锁顺序:发现事务 1 先更新学员表再更新课程表,事务 2 先更新课程表再更新学员表,加锁顺序相反。
- 调整应用代码:统一所有事务的加锁顺序(先学员表后课程表),从根源上消除循环等待。
- 设置锁等待超时:
innodb_lock_wait_timeout=30,避免无限等待。
优化后,选课事务成功率从 82% 提升至 99.5%,死锁告警清零。
4.3.4 常见误区与复盘
- 误区一:认为死锁只发生在多进程环境。单进程内多线程同样可能因竞争锁资源而死锁。
- 误区二:混淆死锁与饥饿。饥饿是进程长期得不到资源但不会阻塞其他进程,而死锁是多个进程互相等待且都无法推进。
- 误区三:忽视资源有序分配法的实际约束。在复杂系统中,为所有资源编号并强制按序申请可能难以实施。
4.4 内存管理:分页、分段与虚拟内存
4.4.1 核心原理:连续分配与离散分配
早期操作系统采用连续内存分配,进程必须占用一整块连续物理内存,导致外部碎片和内部碎片问题严重。现代操作系统普遍采用离散分配方式,将进程地址空间分割成若干块,分别装入物理内存的不同区域。分页与分段是两种主要的离散分配技术。
- 分页存储:将物理内存划分为固定大小的页框(如 4KB),将进程逻辑地址空间划分为等大小的页。通过页表实现逻辑页号到物理页框号的映射。优点是无外部碎片,但页表占用内存且存在页内碎片。
- 分段存储:按程序的逻辑结构(代码段、数据段、栈段)划分为不同长度的段。段表记录段基址与段长。优点是便于共享与保护,但会产生外部碎片。
- 段页式存储:先按逻辑结构分段,每段内再分页,兼顾分段逻辑清晰与分页无外部碎片的优点。
4.4.2 虚拟内存与页面置换算法
虚拟内存技术允许进程在部分装入内存的情况下运行,当访问的页面不在内存时,触发缺页中断,由操作系统从磁盘调入所需页面。若内存已满,则需选择淘汰某个页面,即页面置换。常见置换算法包括:
| 算法 | 策略 | 优点 | 缺点 |
|---|---|---|---|
| 最佳置换(OPT) | 淘汰未来最长时间不被访问的页面 | 缺页率最低 | 无法实现,仅作为理论基准 |
| 先进先出(FIFO) | 淘汰最早进入内存的页面 | 实现简单 | 可能产生 Belady 异常(增加页框反而缺页更多) |
| 最近最少使用(LRU) | 淘汰最长时间未被访问的页面 | 性能接近 OPT | 硬件支持成本高 |
| 时钟算法(Clock) | 循环扫描,淘汰访问位为 0 的页面 | 开销小,性能较好 | 近似 LRU,非精确 |
4.4.3 实战场景:某雷达数据处理系统的虚拟内存调优
某型雷达信号处理机采用 Linux 系统,运行实时目标检测算法,内存需求 8GB,但物理内存仅 4GB。系统启用虚拟内存后,频繁出现缺页中断,导致处理延迟从 20ms 恶化至 200ms。排查过程如下:
- 使用
vmstat 1观察si(swap in)和so(swap out)指标,发现持续大量换页。 - 使用
sar -B查看缺页率,确认主要缺页来自数据段而非代码段。 - 分析算法内存访问模式:目标检测算法对雷达回波矩阵进行多次遍历,数据局部性差。
- 优化措施:将回波矩阵改为内存映射文件(
mmap),并调整vm.swappiness=10降低 swap 倾向;同时将算法中的循环改为分块处理,提升数据局部性。
优化后,缺页率下降 90%,处理延迟稳定在 25ms 以内,满足实时性要求。
4.4.4 常见误区与复盘
- 误区一:认为分页和分段没有区别。分页是系统管理物理内存的手段,对程序员透明;分段是逻辑结构划分,便于共享与保护。
- 误区二:忽略 TLB(快表)的作用。TLB 命中率直接影响访存效率,若 TLB 未命中,需要多次访问内存查询页表,性能急剧下降。
- 误区三:将虚拟内存等同于“无限内存”。虚拟内存受限于磁盘 I/O 速度,过度使用会导致系统抖动(thrashing),CPU 利用率急剧下降。