一、进程的概念、组成、特征
1.1 进程的概念
- 静态与动态:
- 程序是静态存放在磁盘中的可执行文件(如QQ.exe)
- 进程(Process)是程序的一次动态执行过程。
- 本质区别:程序是指令集合的静态文件,进程是动态执行的实例。例如打开三个QQ登录窗口,系统会创建三个独立进程。
1.2 进程的组成 – PID(Process ID, 进程ID)
PID – 操作系统以进程为单位分配CPU、内存等资源,每个进程拥有独立的PID(进程标识符)。
1.2 进程的组成 – PCB(进程控制块)
PID、ID(UID)、进程分配资源情况、进程的运行情况等这些信息都被保存在一个数据结构PCB(Process Control Block)中,即进程控制块操作系统需要对各个并发运行的进程进行管理,但凡管理时所需要的信息,都会被放在PCB中
PCB是给操作系统用的
1.3 进程的组成 – 程序段、数据段
PCB – 给操作系统用的
程序段、数据段给进程自己用的
- 程序段:存放可执行文件的指令序列(如QQ.exe的代码)
- 数据段:存储运行时的变量等数据(如QQ登录账号信息)
- 进程实体(进程映像):严格来说由PCB+程序段+数据段组成,是进程某一时刻的快照状态。
1.4 进程的组成
进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位
1.5 进程的特征
- 动态性:最基本特征,进程有创建→运行→终止的生命周期
- 并发性:多个进程实体可同时存在于内存并发执行
- 独立性:作为资源分配和调度的基本单位(线程引入后调度单位变化)
- 异步性:各进程以不可预知速度推进,需同步机制协调
- 结构性:每个进程均具备PCB+程序段+数据段的标准结构
1.6 进程知识回顾
PCB是进程存在的唯一标志
进程是能独立运行的、独立获得资源、独立接受调度的基本单位
二、进程的状态与转换
2.1 知识总览
2.2 进程的状态 – 创建态、就绪态
创建态
- 定义:进程正在被创建时的状态
- 系统操作:
- 分配内存空间等系统资源
- 完成PCB的初始化工作
- 转换时机:创建完成后进入就绪态
就绪态
- 定义:已具备运行条件但未获得CPU的状态
- 特点:
- 仅缺少CPU资源
- 系统中可能存在多个就绪态进程
- 调度机制:CPU空闲时操作系统会从就绪队列中选择进程运行
2.3 进程的状态 – 运行态
- 定义:进程正在CPU上执行的状态
- 执行特征:CPU正在处理该进程对应的程序指令序列
- 系统限制:
- 单CPU环境下同一时刻最多一个运行态进程
- 多核CPU可并行运行多个进程
2.4 进程的状态 – 阻塞态
- 别称:等待态(Waiting/Blocked)
- 触发条件:
- 等待系统资源分配(如打印机)
- 等待其他进程响应
- 等待特定事件发生
- 特点:进程无法继续执行,必须释放CPU
2.5 进程的状态 – 终止态
- 别称:结束态(Terminated)
- 触发条件:
- 进程主动调用 exit 系统调用
- 遇到不可修复错误(如除零错误)
- 系统操作:
- 回收所有资源(内存、设备等)
- 撤销PCB
- 进程从系统中彻底消失
2.6 进程状态的转换(五状态模型)
- 就绪态→运行态:进程被调度获得CPU
- 运行态→就绪态:
- 时间片用完(时钟中断触发)
- 被更高优先级进程抢占
- 运行态→阻塞态:
- 主动请求等待资源/事件
- 属于进程主动行为(通过系统调用)
- 阻塞态→就绪态:
- 等待的资源/事件已就绪
- 属于被动行为(进程无法控制)
- 创建态→就绪态:系统完成创建相关工作
- 运行态→终止态:进程正常结束或异常终止
通过打印机案例呈现了进程七状态转换
新建态:用户点击打印按钮,打印任务像新生婴儿般诞生,等待被系统接纳进入队列。
就绪态:任务进入打印队列,准备好随时 “开干”,就像运动员在起跑线做好准备。
运行态:打印机选中该任务,开始打印,纸张滚动、油墨喷印,任务正在被执行。
阻塞态:突然缺纸或卡纸,任务被迫暂停,如同施工队因材料不足停下工作,等待问题解决。
终止态:打印完成,任务结束使命,文件输出,任务状态变为终止,如同工作完成的工人退场。
挂起就绪态:系统资源紧张,将就绪队列中暂时不急需打印的任务 “冷藏”,放到外存,处于挂起就绪,等资源充足再唤醒。
挂起阻塞态:阻塞中的任务因系统调整被移到外存,进入挂起阻塞态,等问题解决且资源允许时再恢复。
以上通过打印机案例呈现了进程七状态转换。若你对某个状态转换还有疑问,或想了解更多进程相关知识,欢迎随时说。
判断进程处于挂起就绪态还是挂起阻塞态,关键在于明确进程暂停的原因和当前是否具备执行条件。
从资源占用情况判断
挂起就绪态:进程本身所需的各类资源(如内存、文件句柄等)其实都已经准备齐全,只是因为系统资源紧张,为了给更紧急或优先级更高的进程腾出空间,它被暂时 “挪” 到外存 。就像一场大型活动,观众都已准备好入场,但场馆座位有限,只能在场外等候,一旦场内有空位,就能立即入场。此时进程在等待被系统重新调入内存,进入就绪队列,一旦被调度就能马上执行。
挂起阻塞态:进程存在某种未满足的条件,导致无法执行,比如等待外部设备输入(如打印机缺纸)、等待其他进程释放资源等,并且它也因系统资源管理需要被移到外存。这就好比一个施工队,因缺少关键材料停工,同时还因场地限制被安排到较远的临时营地等待,不仅要等材料到位,还得等系统重新分配资源、调入内存后,才有可能继续执行。
依据任务执行条件判断
对于挂起就绪态的进程,只要系统将其重新调入内存,放入就绪队列,它就随时可以执行,不需要等待外部条件的改变 ,如打印机任务因内存不足被挂起,当内存充足时,无需其他条件即可准备执行。
而挂起阻塞态的进程,即便系统将其调入内存,若阻塞它的条件(如设备未就绪、资源未释放)不解决,它依旧无法执行。比如因打印机卡纸进入挂起阻塞态的任务,即使被重新调入内存,在卡纸问题解决前,也无法开始打印。
2.7 三种基本状态
运行态、就绪态、阻塞态三种基本状态
进程PCB中,会有一个变量 state来表示进程的当前状态。如:1表示创建态、2表示就绪态、3表示运行态…
为了对同一个状态下的各个进程进行统一的管理,操作系统会将各个进程的PCB组织起来。
- 核心状态:
- 运行态(Running):占有CPU并执行
- 就绪态(Ready):具备运行条件但无CPU
- 阻塞态(Blocked):因等待事件无法运行
- 特殊状态:
- 创建态(New):正在分配资源和初始化PCB
- 终止态(Terminated):正在回收资源和撤销PCB
2.8 进程的组织 – 链接方式
为了对同一个状态下的各个进程进行统一的管理,操作系统会将各个进程的PCB组织起来,通过两种方式组织 – 链接方式、索引方式
- 队列结构:
- 执行指针:指向当前运行态进程PCB
- 就绪队列:按优先级排序(高优先级在队头)
- 阻塞队列:可按等待资源类型细分
- 管理优势:便于操作系统统一调度管理
2.9 进程的组织 – 索引方式
- 实现方式:
- 为不同状态建立索引表
- 表项指向对应PCB
- 应用现状:多数操作系统采用链接方式
2.10 知识回顾(绿色为高频考点)
三、进程控制
3.1 知识总览
3.2 进程控制的概念
什么是进程控制?进程控制就是要实现进程状态转换
- 核心功能:对系统中所有进程实施有效管理,包括创建新进程、撤销已有进程、实现进程状态转换等。
- 简化理解:本质是实现进程状态转换(如创建态→就绪态→运行态→终止态/阻塞态)
3.3 如何实现进程控制?
原语关键特性:两条指令之间的代码段具有不可中断性
3.4 为什么要用原语实现?
从state这个变量来看,它的状态是就绪态;但是从它所处的队列来看,这个PCB2此时又还是在阻塞队列当中。所以这就导致了PCB2这两个信息对不上了。
如果不能“一气呵成”,就有可能导致操作系统中的某些关键数据结构信息不统一的情况,这会影响操作系统进行别的管理工作
所以要用原语实现
3.5 如何实现原语的“原子性”
正常情况:CPU每执行完一条指令都会例行检查是否有中断信号需要处理,如果有,则暂停运行当前这段程序,转而执行相应的中断处理程序。
原语的原子性实现
- 原语的两个特权指令实现原子性:通过特权指令”关中断”和”开中断”实现
- 关中断:执行后CPU不再检查中断信号,保证后续指令序列不被中断
- 开中断:恢复中断检查机制
- 使用原语的目的:防止进程状态转换过程中出现数据不一致(如PCB状态变量与队列位置不符)
思考:如果这两个特权指令允许用户程序使用的话,会发生什么情况?
若在用户程序中滥用这两条指令,会导致程序独占CPU资源,所以开中断指令、关中断指令是特权指令,只能让内核使用,不能让普通的用户使用
3.6 进程控制相关的原语(程序)- 进程的创建
创建原语:
- 步骤:申请空白PCB→分配资源→初始化PCB→插入就绪队列
- 触发事件:
- 用户登录(分时系统)
- 作业调度(批处理系统)
- 服务请求(如I/O操作)
- 应用请求(创建子进程)
作业 – 此时还在外存中,还未运行的程序
作业调度 – 所谓的作业调度就是指从外存当中挑选一个程序,让它把它放入内存,让它开始运行。
3.7 进程控制相关的原语(程序)- 进程的终止
撤销原语:
- 步骤:查找终止进程PCB→剥夺CPU→终止子进程→归还资源→删除PCB
- 引起进程终止的事件触发事件:
- 正常结束(任务完成)
- 异常结束(如除零错误)
- 外界干预(如kill命令)
3.8 进程控制相关的原语(程序)- 进程的阻塞与唤醒
进程的阻塞
- 触发条件:运行态进程主动请求等待某事件(如I/O完成)
- 执行步骤:
- 保护进程现场(保存寄存器等运行环境)
- 修改PCB状态为阻塞态
- 将PCB移入对应等待队列
- 现场保护:保存CPU寄存器值、程序计数器等上下文信息到PCB
- 队列机制:不同事件对应独立等待队列(如磁盘I/O队列、打印机队列等)
进程的唤醒
- 触发条件:进程等待的事件发生时(如I/O操作完成)
- 执行步骤:
- 从等待队列移除PCB
- 修改状态为就绪态
- 插入就绪队列等待调度
- 资源继承:子进程终止时资源归还父进程(如示例中访达进程管理子进程内存)
配对原则:唤醒原语必须与阻塞原语成对出现
3.9 进程控制相关的原语(程序)- 进程的切换
切换原语的功能
- 状态转换: 切换原语会让正在运行的进程下处理机回到就绪队列,同时从就绪队列中选择一个就绪态进程上处理机运行
- PCB操作:
- 将进程的运行环境信息存入PCB
- 把进程的PCB移到相应队列(如下处理机进程的PCB回到就绪队列)
- 挑选新进程并更新其PCB内容
- 从新进程的PCB中恢复其运行环境
3.10 进程切换中提到的保存运行环境
PSW(程序状态字寄存器):保存CPU状态(内核态/用户态)
PC(程序计数器):存放下一条指令地址
IR(指令寄存器):存放当前执行指令
通用寄存器:存放运算中间结果
- 运行环境保存与恢复 – 实现并发的关键技术
- 环境保存: 寄存器为CPU共享资源,进程切换时需保存当前进程的寄存器值到PCB,防止被其他进程覆盖
- 恢复过程: 当进程重新获得CPU时,从PCB恢复之前保存的寄存器值,保证程序能从中断处继续执行
思考:执行完指令3后,另一个进程开始上CPU运行。
注意:另一个进程在运行过程中也会使用各个寄存器解决办法:在进程切换时先在PCB中保存这个进程的运行环境保存一些必要的寄存器信息
当原来的进程再次投入运行时,可以通过PCB恢复它的运行环境
3.11 知识回顾
原语三大操作:
- 更新PCB信息(状态/运行环境)
- 将PCB插入合适队列
- 资源分配/回收(创建/终止时)
四、进程通信(Inter-Process Communication, IPC)
进程通信的三种方式:共享存储、消息传递、管道通信
4.1 什么是进程间通信
- 定义: 进程间通信(Inter-Process Communication,IPC)是指两个或多个进程之间产生数据交互的过程。
- 必要性: 在系统运行多个进程时,进程间需要相互配合工作,例如微博分享文章到微信的过程就涉及进程通信。
- 实例: 微博应用通过内置分享功能将内容传递给微信应用,实现跨进程数据交互。
4.2 为什么进程通信需要操作系统支持
- 安全机制: 各进程内存地址空间相互独立,进程P不能直接访问进程Q的地址空间,防止恶意软件窃取数据。
- 由于进程间内存隔离,必须通过操作系统内核提供的机制才能完成数据交换。
- 安全示例: 若允许进程随意访问其他进程空间,可能导致微信聊天记录等隐私数据被恶意程序读取。
4.3 进程通信方式- 共享存储 – 原理
- 核心思想: 通过操作系统创建可被多个进程共同访问的共享存储区实现通信。
- 实现步骤:
- 进程使用shm_open系统调用申请共享内存区
- 各进程通过mmap将共享区映射到自身虚拟地址空间
- 通过增加页表项/段表项建立映射关系(第三章详细说明)
- 同步要求: 需保证各进程对共享区的互斥访问,可通过PV操作等同步机制实现。
共享存储分类:基于数据结构的共享、基于存储区的共享
1、基于存储区的共享
特点:
- 操作系统划定固定大小区域(如4KB)
- 进程自由决定数据存储位置和方式
优势: 灵活性高,传输速度快,属于高级通信方式
应用: Linux系统中通过shm_open和mmap系统调用实现
2、基于数据结构的共享
特点:
- 操作系统限定共享区域的数据结构(如长度固定的数组)
- 进程必须按预定格式读写数据
限制: 灵活性差,传输速度慢,属于低级通信方式
示例: 共享全局变量,但只能按int a[3]这样的固定结构访问
4.4 进程通信方式 – 消息传递
1、基本单位: 以格式化的消息(Message)为单位进行数据交换
2、组成结构:
- 消息头: 包含发送/接收进程ID、消息长度等格式化的信息
- 消息体: 实际传输的数据内容
3、通过操作系统提供的”发送消息/接收消息” 两个原语完成通信
4、分类:直接通信方式\间接(信箱)通信方式
消息传递(直接通信方式)
- 实现机制:
- 发送进程需明确指定接收进程的PID,如send(Q,msg)
- 操作系统内核维护各进程的消息队列(存储在PCB中)
- 发送原语将消息从用户空间复制到内核空间,并挂到目标进程的消息队列
- 接收原语从内核空间将消息复制回用户空间,如receive(P,&msg)
- 特点:
- 点对点通信,需要”指名道姓”
- 消息传递路径:发送进程→内核→接收进程
消息传递(间接通信方式、信箱通信方式)
- 中间实体: 通过”信箱”(mailbox)作为消息传递的中介
- 工作流程:
- 进程通过系统调用申请信箱(如信箱a、信箱b)
- 发送进程指明目标信箱而非接收进程ID
- 接收进程从指定信箱获取消息
- 特点:
- 又称信箱通信方式
- 可以多个进程往同一个信箱send消息,也可以多个进程从同一个信箱中receive消息
- 解耦发送和接收进程的直接依赖关系
4.5 进程通信方式 – 管道通信
先说一下管道通信方式和共享存储方式的区别
管道:严格先进先出,读写位置固定
共享存储:随机访问,无顺序限制
管道通信原理(类似水管)
- 本质: 特殊的共享文件(pipe文件),实际是内存中的固定大小缓冲区
- 数据结构: 实现为循环队列,遵循先进先出原则
- 读写规则:
- 写满时写进程阻塞,读空时读进程阻塞
- 写进程可随时写入(只要管道未满)
- 读进程可随时读取(只要管道未空)
- 通信特性:
- 半双工通信,数据流向单向
- 实现双向通信需建立两个管道
- 操作系统保证访问互斥,例如P、V操作
这里对第五点做决定:考试写第一种方式:一个管道允许多个写进程,一个读进程的方式
半双工通信 – 同一时刻只支持单向数据流动,进程结束后,方向可以反过来
4.6 课本勘误
1、写进程往管道写数据,即便管道没被写满,只要管道没空,读进程就可以从管道读数据
2、读进程从管道读数据,即便管道没被读空,只要管道没满,写进程就可以往管道写数据
4.7 知识总结
五、线程概念多线程模型
5.1 什么是线程,为什么要引入线程?
并发需求:传统进程只能串行执行程序代码,无法满足像QQ同时进行视频聊天、文字聊天和文件传输等多任务需求。
传统进程中进程是程序执行流的最小单位,导致一个进程内无法实现多任务并发
线程作为”轻量级进程”被引入,使得一个进程内可以创建多个执行流
- 实际应用:QQ的不同功能(如视频、文字、文件传输)可以分配到不同线程并发执行
- 引入线程后,线程成为程序执行流的最小单位,允许更细粒度的并发控制
- 资源分配:
- 传统:进程是资源分配和调度的基本单位
- 引入线程后:进程只作为除CPU之外的系统资源分配的基本单位,线程成为基本的CPU执行单元,也是程序执行流的最小单位,线程也作为处理机的分配单元
- 并发性:
- 传统:只能实现进程间并发
- 引入线程后:可实现线程间并发,显著提升系统并发度
5.2 引入线程机制后,有什么变换
- 资源管理:引入线程后,进程仅作为除CPU外系统资源(如打印机、内存地址空间)的分配单元
- 调度单位:CPU直接调度线程而非进程,实现更高效的资源利用
- 并发性:
- 传统:只能实现进程间并发
- 引入线程后:可实现线程间并发,显著提升系统并发度
- 系统开销:
- 传统:进程切换需要完整切换运行环境,开销大(类比图书馆换陌生人用桌子需要搬书)
- 引入线程后:同进程内线程切换不需切换进程环境,开销小(类比舍友共用桌子不需搬书)
5.3 线程的属性
- 调度单位:线程是处理机调度的基本单位,多核CPU中不同线程可分配到不同核心
- 管理结构:每个线程有唯一线程ID和线程控制块(TCB),管理线程状态和资源
- 状态转换:与进程类似,线程也有就绪、阻塞、运行三种基本状态
- 资源共享:
- 线程几乎不拥有系统资源,共享所属进程的资源(如I/O设备、内存地址空间)
- 同进程线程通信可直接通过共享内存实现,无需系统干预
- 切换开销:
- 同进程内线程切换不会引起进程切换,开销小
- 跨进程线程切换会引起进程切换,需要切换完整运行环境,开销大
- 执行单元:线程是基本CPU执行单元和程序执行流的最小单位
- 并发优势:不仅进程间可以并发,进程内各线程也可并发,显著提升系统并发度
- 资源分配:进程作为资源容器,线程作为执行单元,实现资源与调度的分离
六、线程的实现方式&多线程模型
6.1 线程的实现方式 – 用户级线程(ULT, User-Level Thread)
- 历史背景:早期操作系统(如Unix)只支持进程不支持线程,线程功能由线程库实现
- 实现原理:应用程序通过线程库管理线程,操作系统只能看到进程
- 代码示例:最简单的线程库模拟 – 通过while循环和if语句实现简单线程调度(如QQ同时处理视频/文字/文件传输)
关于用户级线程的几个问题
1、线程的管理工作由谁来完成?
答:用户级线程由应用程序通过线程库实现,所有的线程管理工作都由应用程序负责(包括线程切换)
2、线程切换是否需要CPU变态?
答:用户级线程中,线程切换可以在用户态下即可完成,无需操作系统干预,所以不需要CPU变换状态。
3、操作系统是否能意识到用户级线程的存在?
答:在用户看来,是有多个线程。但是在操作系统内核看来,并意识不到线程的存在。“用户级线程”就是“从用户视角看能看到的线程
4、这种线程的实现方式有什么优点和缺点?
答:以下是优点和缺点
优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高缺点:当用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行。
6.2 线程的实现方式 – 内核级线程(KLT, kernel-Level Thread)
又叫内核支持线程 – 操作系统支持的线程
- 现代实现:由操作系统直接支持(如Windows/Linux)
- 管理机制:操作系统为每个线程建立TCB(Thread Control Block)
关于内核级线程的几个问题
1、线程的管理工作由谁来完成?
答:内核级线程的管理工作由操作系统完成
2、线程切换是否需要CPU变态?
答:线程调度、切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成。
3、操作系统是否能意识到内核级线程的存在?
答:操作系统会为每个内核级线程建立相应的TCB(Thread Control Block,线程控制块)通过TCB对线程进行管理。“内核级线程”就是“从操作系统内核视角看能看到的线程”。
4、这种线程的实现方式有什么优点和缺点?
答:优缺点如下
优点:当一个线程被阻塞后,别的线程还可以继续执行办并发能力强。多线程可在多核处理机上并行执行。
缺点:一个用户进程会占用多个内核级线程线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。
6.3 多线程模型 – 一对一模型
在支持内核级线程的系统中,根据用户级线程和内核级线程的映射关系,可以划分为几种多线程模型
6.4 多线程模型 – 多对一模型
多对一这种模型:相当于退化到用户级
操作系统只“看得见”内核级线程,因此只有内核级线程才是处理机分配的单位。
6.5 多线程模型 – 多对多模型
多对多模型定义:n用户级线程映射到m个内核级线程(n>=m)每个用户进程对应m个内核级线程。
优点:
1、克服了多对一模型并发度不高的缺点(一个阻塞全体阻塞)
2、又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点
6.6 知识回顾
七、线程的状态与转换
7.1 线程的状态与转换介绍
核心状态:线程状态重点关注运行态、就绪态和阻塞态三种核心状态,其转换机制与进程状态转换完全一致。
状态转换:
运行→就绪:当运行态线程分配的时间片用完时,会下处理机进入就绪态
就绪→运行:就绪态线程被调度程序选中时,会上处理机进入运行态
运行→阻塞:当线程发出等待事件请求(如I/O操作)时,会从运行态转为阻塞态
阻塞→就绪:当阻塞线程等待的事件发生时,会从阻塞态回到就绪态
7.2 线程的组织与控制
线程控制块(TCB)
- 基本组成:
- 标识符:TID(线程ID),功能类似进程的PID
- 执行上下文:
- 程序计数器PC:记录线程当前执行位置
- 通用寄存器:保存代码运行的中间结果
- 堆栈指针SP:指向保存函数调用链和局部变量的内存区域
- 状态信息:明确记录线程当前状态(运行/就绪/阻塞)及阻塞原因
- 优先级:作为线程调度和资源分配的依据
- 组织方式:
- 多个TCB可组成线程表,可按进程分类、全局统一或按状态分类管理
- 具体组织形式由系统需求决定
线程切换时要保存/恢复
本网站原创文章版权归何大锤的狂飙日记所有。发布者:何大锤,转转请注明出处:何大锤的博客