进程与线程
进程 vs 线程
进程是系统资源分配的基本单位(运行的应用程序)
线程是任务调度和执行的基本单位(线程是进程的子集)
维度 | 进程(Process) | 线程(Thread) |
---|---|---|
核心角色 | 系统资源分配的基本单位 | CPU任务调度与执行的基本单位 |
本质 | 运行中的应用程序,是程序的一次动态执行 | 进程的子集(轻量级进程),共享进程资源 |
关键差异 | 资源独立(内存、文件描述符等),切换重 | 共享进程资源,仅私有栈 / 寄存器,切换轻量 |
进程
1. 进程的本质与组成
● 静态 vs 动态:
程序是静态指令的集合(例如 .exe
文件),而进程是程序的动态执行过程(从创建到终止的整个生命周期)。
● 唯一标识:
进程通过 进程 ID(PID) 进行唯一标识,其核心标志是 进程控制块(PCB),PCB 是进程存在的关键数据结构。
● 核心组成(三部分):
- 程序段:用于存放待执行的指令;
- 数据段:用于存放运行时的变量和数据;
- PCB(Process Control Block):记录进程的状态、资源占用情况、优先级等关键信息,是操作系统管理进程的核心数据结构。
进程的五大特征
- 动态性
- 进程具有从创建、运行、阻塞到终止的完整生命周期,而程序本身不具备生命周期。
- 并发性
- 多个进程可以在系统中交替执行,这种并发性通过 CPU 的时分复用技术实现。
- 独立性
- 每个进程拥有独立的资源空间(如内存、文件等),彼此之间互不干扰。
- 异步性
- 进程的执行速度无法预测,完全由调度算法决定,因此需要通过同步机制来协调进程间的协作。
- 结构性
- 进程的结构固定,由“程序段 + 数据段 + PCB(进程控制块)”三部分组成。
进程之间切换状态
如图可以看出里面的状态,对应进程不同状态。
- 定义:从一个进程切换到另一个进程时,需保存 / 恢复进程的运行状态(确保后续可继续执行)。
- 切换内容:
- 用户空间:虚拟内存、栈、全局变量(进程独立资源);
- 内核空间:内核栈、寄存器(如程序计数器 PC、指令寄存器 IR,记录执行位置)。
- 特点:切换成本高(需切换虚拟内存映射),因此操作系统需减少不必要的进程切换。
PCB中标识状态state
进程创建,初始化PCB
进程终止:会发起exit的系统调用,然后回收进程的资源和PCB
这里要提一个特别的状态,阻塞态,我们知道程序会放在物理内存中运行,但是如果很多程序一直在阻塞,物理内存会过大,所以我们会将物理内存交换到物理磁盘里面,避免内存过大,导致程序崩溃。
这时候就会有个状态叫做挂起,挂起:没有实际占用物理内存的状态
- 阻塞挂起状态:等待事件完成,然后进入内存
- 就绪挂起状态:只要进入内存就会直接执行
从图中获得:
- 运行态和就绪态是相互切换的,然后就绪态有调度任务给他,就会变成运行态,用完时间片之后变成就绪态
- 也就是说,cpu运行程序是时分法
- 阻塞态是缺少资源,但是不包括时间片
- 除了就绪态和运行态之外,都是单向的
进程的组织–链接形式
执行指针-> 优先级高的会在前面
就绪队列->
阻塞队列->
进程控制
定义:实现进程状态转换
使用原语实现,保证状态要么转化成功,要么转化失败,保证原子性。
如何实现原语的原子性?
通过关中断和开中断两个特权指令实现原子性。
和事务有点像,就是关中断执行后,不接收其他中断指令,只有等待指令执行完成之后,启动开中断才会进行其他指令。从而保证原子性。
进程的上下文切换
一个进程切换到另一个进程
涉及切换,就需要保存上一个线程的状态
- 用户空间:虚拟内存,栈,全局变量
- 内核空间:栈堆,寄存器
原语分类
创建
终止
阻塞
唤醒
切换
简单理解就是:
- 更新pcb信息
- 插入合适队列
- 分配/回收资源
进程通信
定义:两个进程之间数据交互
各个进程的内存空间是相互独立的,所以只能进程进行通信
两种方式
- 共享内存,直接读取内存,但是会有同步问题,需要保证读取和新增的互斥
- 消息传递
- 直接通信,通过pid发送信息
- 申请自己的信箱,然后别人发送
- 管道传递
(1)进程通信:解决 “内存独立” 导致的数据交互问题
因进程内存空间隔离,需通过专用机制实现数据交互,核心方式有 3 种:
- 共享内存:多个进程共享一块物理内存,效率最高,但需解决同步互斥问题(避免同时读写导致数据错乱);
- 消息传递:
- 直接通信:通过对方 PID 直接发送消息;
- 间接通信:进程创建 “信箱”,其他进程向信箱发送消息;
- 管道传递:半双工通信(单向数据流),常用于父子进程。
(2)信号:进程的 “事件通知机制”
- 定义:操作系统向进程发送的 “事件通知”(如中断信号、退出信号),进程收到后执行预设处理逻辑(如忽略、终止、执行自定义函数)。
信号
定义:通知进程某个事件已经发生,进程收到信号,对该信号进行处理
线程
CPU调度和执行的基本单位,轻量级进程
传统进程是串行执行,为了并发量,引入线程。
状态转换
线程的组织与控制
处理机调度
调度:有限资源在规定时间内合理分配任务
进程调度
1. 调度时机:何时触发进程切换
触发类型 | 具体场景 |
---|---|
主动触发 | 1. 进程正常终止;2. 进程发生异常;3. 进程主动请求阻塞(如 I/O) |
被动触发 | 1. 进程时间片用完;2. 高优先级进程进入就绪队列;3. 紧急事件处理(如中断) |
不可调度 | 1. 处理中断过程中;2. 进程处于内核临界区(独占资源);3. 执行原子操作时 |
内核临界区:某一时间段内仅允许一个进程访问的内核资源(如内存管理模块),需保证独占性。
2. 调度方式
- 非剥夺调度(非抢占式):进程主动放弃 CPU 后才调度其他进程,适用于批处理系统(如 AI 模型训练、数据批量处理),优点是开销低、无抢占冲突。
- 剥夺调度(抢占式):高优先级进程可直接抢占低优先级进程的 CPU,适用于分时系统 / 实时系统(如游戏、打字软件),优点是响应速度快。
进程切换
- 原来运行进程各个数据保存
- 恢复要执行的进程数据
调度器/调度程序
决定因素
- 谁运行
- 时间
调度算法
1. 先来先服务(FCFS,First-Come, First-Served)
- 原理
按照进程进入就绪队列的先后顺序进行调度,先进入队列的进程优先执行。 - 优点
- 实现简单。
- 公平性高,不会产生“饥饿”现象。
- 缺点
- 对短进程不友好,若长进程先到达,会导致短进程等待时间过长。
- CPU 利用率低。
2. 短作业优先(SJF,Shortest Job First)
- 原理
从就绪队列中选择预计运行时间最短的进程投入运行。 - 优点
- 平均周转时间和平均等待时间较短。
- 能有效提高系统吞吐量。
- 缺点
- 难以准确预知作业运行时间。
- 可能导致长作业“饥饿”,对长作业不公平。
3. 最短剩余时间优先(SRTF,Shortest Remaining Time First)
- 原理
它是 SJF 的抢占式版本,每当有新进程进入就绪队列且其剩余运行时间比当前正在执行进程的剩余时间更短时,就抢占当前进程的 CPU 资源。 - 优点
- 能及时响应短进程。
- 平均等待时间和周转时间较短。
- 缺点
- 需要不断计算剩余时间,系统开销较大。
- 同样存在长作业“饥饿”问题。
4. 时间片轮转(RR,Round Robin)
- 原理
将 CPU 时间划分为固定大小的时间片,就绪队列中的每个进程轮流运行一个时间片。若时间片用完进程未执行完,则将其放回就绪队列末尾,等待下一轮调度。 - 优点
- 能快速响应用户请求,适用于分时系统。
- 保证每个进程都能得到及时处理。
- 缺点
- 时间片设置过短会导致频繁的进程切换,增加系统开销。
- 时间片过长则退化为 FCFS。
5. 优先级调度算法
- 原理
为每个进程分配一个优先级,调度时选择优先级最高的进程执行。优先级可静态分配(创建进程时确定,运行中不变)或动态分配(根据进程的运行情况调整)。 - 优点
- 可根据进程的重要程度合理分配资源,例如保证关键系统进程优先执行。
- 缺点
- 若低优先级进程长期得不到调度,会产生“饥饿”现象。
6. 多级反馈队列调度算法
- 原理
设置多个优先级不同的就绪队列,每个队列对应不同的时间片(优先级越高,时间片越短)。新进程先进入最高优先级队列,按时间片轮转方式执行,若在一个时间片内未执行完,则降低优先级进入下一级队列,依此类推。 - 优点
- 结合了 FCFS、RR 和优先级调度算法的优点。
- 既能及时响应短进程,又能兼顾长进程。
- 还能保证优先级高的进程优先执行。
- 缺点
- 算法复杂度较高,需要合理设置队列数量、优先级和时间片大小。
1)多级反馈队列调度(MLFQ):平衡响应速度与公平性
MLFQ 是综合 “先来先服务(FCFS)、时间片轮转、优先级调度” 的经典算法,核心规则如下:
- 队列结构:多个就绪队列,优先级从高到低(一级队列优先级最高),时间片从短到长(一级 10ms、二级 20ms、三级 40ms 等);
- 新进程入队:新进程先进入一级队列,按 FCFS 排队;
- 时间片处理:若进程在当前队列时间片内未执行完,“下放” 到低一级队列末尾;
- 调度顺序:高优先级队列空时,才调度低优先级队列(“先高后低”);
- 抢占性:低优先级进程运行时,若高优先级队列有新进程,立即抢占 CPU;
- 避免饥饿:低优先级队列中等待过久的进程(如超过阈值),“升级” 到高优先级队列;
- 短作业优势:短作业可在高优先级队列的时间片内完成,响应速度快;长作业逐渐下放,不会被饿死。
(2)多级队列调度:按进程类型分类调度
- 核心逻辑:按进程用途划分多个独立队列(如系统进程队列、交互式进程队列、批处理进程队列),每个队列采用不同调度策略:
- 系统进程队列(内存管理):高优先级,抢占式调度;
- 交互式进程队列(游戏、打字):中优先级,时间片轮转;
- 批处理进程队列(AI 训练):低优先级,FCFS。
(3)多处理机调度(多核 CPU 场景)
核心目标:负载均衡(各 CPU 负载均匀)+ 处理机亲和性(进程尽量在固定 CPU 执行,减少缓存失效)。实现方案:
队列类型 | 核心逻辑 | 优点 | 缺点 |
---|---|---|---|
公共就绪队列 | 所有 CPU 共享一个就绪队列,互斥访问 | 天然负载均衡 | 频繁切换 CPU,亲和性差 |
私有就绪队列 | 每个 CPU 有独立就绪队列,通过 “迁移策略” 平衡负载 | 亲和性好,切换成本低 | 需额外维护负载均衡 |
- 迁移策略:
- Push 迁移:周期性检查各 CPU 负载,将繁忙 CPU 的任务 “推” 给空闲 CPU;
- Pull 迁移:空闲 CPU 主动 “拉取” 繁忙 CPU 的任务。
补充
- 虚拟内存与进程切换:每个进程有独立虚拟内存空间,操作系统需维护 “虚拟内存→物理内存” 映射表;进程切换时需同步切换映射表,这是进程切换成本高的核心原因之一。
- 操作系统的核心作用:作为 “硬件与应用程序的中间层”,管理 CPU、内存、磁盘等硬件资源,合理分配给进程 / 线程,确保应用程序高效、稳定运行。
- 原语与事务的类比:原语的原子性与数据库 “事务” 类似 —— 执行过程中不响应外部中断,确保操作连续、不可拆分(如创建原语需同时完成 PCB 初始化、资源分配、入队,缺一不可)。
- 计算机核心资源:
- 处理资源:CPU、寄存器(程序计数器 PC、指令寄存器 IR 等,记录指令执行状态);
- 存储资源:物理内存、物理磁盘;
- 通信资源:文件描述符、网络端口。