02.进程管理
# 01.进程管理
# 1、进程与线程
1)什么是进程?
进程是操作系统
资源分配的基本单位
进程控制块(Process Control Block,PCB)保存了进程的基本信息和运行状态
如进程标识符、程序计数器、内存地址、I/O状态等
系统通过对 PCB 的操作来管理进程的创建与撤销
2)什么是线程?
- 线程是独立
调度的基本单位
- 一个进程可以包含多个线程,线程共享进程的资源,如内存、文件描述符等
- 线程允许并发执行,从而提高程序的效率
- 线程是独立
区别:
资源:进程拥有独立的资源,而线程共享进程资源
调度:
- 线程是调度的基本单位,线程切换在同一进程中开销小
- 跨进程的线程切换则涉及进程切换
系统开销:
- 进程的创建和销毁开销比线程大
- 进程切换涉及完整的资源上下文切换,而线程切换只需切换少量寄存器内容
通信:
- 线程之间可以共享进程内的数据,进程之间的通信需要借助进程间通信(IPC)机制
# 2、进程状态的切换
进程三种状态
就绪状态(ready):进程已准备好运行,等待调度
运行状态(running):进程正在占用 CPU
阻塞状态(waiting):进程因等待某些资源(非 CPU 资源)而暂停
状态切换中:
就绪态和运行态之间可以相互转换
阻塞态由运行态进入,等待资源后再转换为就绪态
# 3、进程调度算法
- 进程调度算法的目标因系统类型而异
- 1)批处理系统:注重吞吐量和周转时间
- 先来先服务(FCFS):非抢占式,按照到达顺序调度适合长作业,短作业等待时间长
- 短作业优先(SJF):非抢占式,优先调度预计时间最短的作业长作业可能饿死
- 最短剩余时间优先(SRTN):
- 抢占式,按剩余时间调度
- 新作业的运行时间小于当前进程时会抢占
- 2)交互式系统:强调响应时间
- 时间片轮转:进程按顺序排队,每个进程分配一个时间片,时间片过后切换
- 优先级调度:按进程优先级调度,避免低优先级进程一直被延迟
- 多级反馈队列:
- 设置多个队列,每个队列的时间片不同
- 进程执行不完就降级至下一个队列,综合时间片轮转和优先级调度
- 3)实时系统:需要在限定时间内响应,分为硬实时和软实时系统
# 4、进程同步
- 进程同步确保多个进程协调执行,避免数据冲突
- 临界区:
- 访问共享资源的代码段
- 在进入临界区前,进程需要检查是否可以安全进入
- 同步与互斥:
- 同步:进程间需按特定顺序执行
- 互斥:某一时刻只有一个进程能进入临界区
- 信号量:
- 是用于控制进程同步的整型变量,支持
down
(P)和up
(V)操作 - 互斥量(Mutex)是信号量的一种特殊形式,用于互斥访问临界区
- 是用于控制进程同步的整型变量,支持
- 管程:
- 是一种高级同步机制,通过封装共享资源的访问操作,简化进程的同步操作
- 管程使用条件变量和
wait
、signal
操作来同步进程
# 5、经典同步问题
- 哲学家进餐问题:
- 多个哲学家共享资源(筷子),如果不加控制可能导致死锁
- 解决方案包括允许一个哲学家同时拿起两只筷子,或者确保邻居哲学家不同时进餐
- 读者-写者问题:
- 允许多个进程同时读数据,但不允许同时写入或读写同时发生
- 为此,使用信号量
count
记录读进程的数量 - 互斥量
count_mutex
和data_mutex
来分别控制对读计数器和数据的访问
# 6、进程通信
- 管道:单向通信的方式,数据以字节流形式在父子进程之间传递
- FIFO:类似管道,但允许无关进程之间的通信
- 消息队列:通过消息传递数据,支持进程间的异步通信
- 信号量:用于进程同步,也可以通过信号量进行简单通信
- 共享内存:多个进程可以直接访问相同的内存区域,通信速度快,但需要同步机制防止数据冲突
- 套接字:用于不同主机之间的进程通信,支持网络通信
# 02.死锁
- 在操作系统中,死锁是指
两个或多个进程相互等待对方释放资源
,导致它们都无法继续执行的现象
# 1、死锁的四个必要条件
要发生死锁,必须满足以下四个条件(同时成立)
互斥条件:
一个资源一次只能被一个进程使用请求与保持条件:
一个进程因请求资源而阻塞时,对已获得资源保持不放不剥夺条件:
进程获得的资源,在未完全使用完之前,不能强行剥夺循环等待条件:
若干进程之间形成一种头尾相接的环形等待资源关系
# 2、死锁的处理方法
# 1)鸵鸟策略
- 该策略是指操作系统选择忽视死锁,不采取任何预防措施
- 这是因为解决死锁的代价可能很高,而死锁发生的概率较低,或者影响较小
- Unix、Linux 和 Windows 等系统通常采用鸵鸟策略
# 2)死锁检测与恢复
死锁检测和恢复方法并不试图防止死锁的发生,而是在死锁发生后检测它们并采取措施解决
根据资源的分配方式,可以分为两类:
每种类型一个资源的死锁检测:
- 使用资源分配图来表示资源和进程的关系
- 通过检测资源分配图中是否存在环路来判断死锁
每种类型多个资源的死锁检测:
- 通过矩阵算法,表示进程对资源的请求和分配
- 检测进程能否继续执行,若进程无法满足资源请求并且不可终止,则判断为死锁
死锁恢复方法:
- 资源抢占:强制回收某些资源,将其分配给其他进程、
- 回滚恢复:将进程回滚到某个安全状态、
- 终止进程:直接杀死某些进程以释放资源、
# 3)死锁预防
- 在程序执行之前通过限制系统资源的分配方式来预防死锁
- 这种策略通过破坏死锁发生的四个必要条件之一来实现
- 破坏互斥条件:如使用假脱机打印技术,使多个进程能够同时打印,而只需要最后打印时占用打印机资源、
- 破坏占有和等待条件:要求进程在启动时一次性申请所有资源,而不是在运行过程中逐步请求、
- 破坏不可抢占条件:当一个进程请求一个无法立即满足的资源时,它必须释放已经占有的所有资源、
- 破坏环路等待条件:为资源统一编号,进程必须按照编号顺序请求资源,防止形成环路、
# 4)死锁避免
死锁避免策略依赖于系统在程序运行时动态地管理资源分配,确保系统始终处于安全状态
一种常见的避免算法是银行家算法、
银行家算法:
- 该算法基于进程的最大资源需求进行判断
- 只有当系统能够在某个进程申请资源后仍保持安全状态时,才允许分配资源、
银行家算法可应用于单资源和多资源情形
单个资源的银行家算法:
- 如果满足进程的资源请求可能导致系统进入不安全状态,则拒绝该请求
多个资源的银行家算法:
- 通过矩阵来表示资源分配,系统需要检查当前状态是否安全
- 如果某个资源请求导致进入不安全状态,则拒绝分配
# 03.常见问题
# 1、进程和线程的区别?
调度:进程是资源分配的基本单位,而线程是CPU调度的基本单位、
切换:线程的上下文切换比进程快,因为不涉及内存地址空间的切换、
资源管理:
- 进程拥有独立的资源(如内存、文件句柄等)
- 线程不独立拥有资源,但可以访问所属进程的资源、
系统开销:
创建和销毁进程时需要操作系统分配和回收大量资源,如内存和文件描述符,开销较大、
创建和销毁线程的开销较小,线程切换也比进程切换更高效、
# 2、协程与线程的区别?
执行方式:线程是并发执行的同步机制,协程是非抢占式的异步机制、
抢占性:
- 线程的调度由操作系统决定,可以随时被中断;
- 协程由用户代码控制,只有在主动释放时才会切换,适合单线程任务调度、
控制与管理:
协程由用户态管理,不依赖操作系统内核、线程由操作系统内核调度和管理、
一个线程可以包含多个协程,协程的执行可以在多个线程或线程池中调度、
状态保持:
- 协程可以在挂起时保存状态,并在下次调用时恢复,适合需要暂停和恢复的场景、
# 3、并发和并行有什么区别?
并发:在一段时间内多个任务交替执行,通常指单核环境下通过快速切换来实现宏观上的“同时”运行、
并行:多个任务在同一时刻同时执行,要求多核处理器,多个任务可以真正物理上并行处理、
# 4、进程与线程的切换流程?
进程切换
- 切换页表,使用新的地址空间,导致缓存的内存地址失效、
- 切换内核栈和硬件上下文(如寄存器等)、
线程切换
- 由于线程共享进程的地址空间,线程切换无需切换页表,仅需切换内核栈和硬件上下文
相比之下,进程切换的开销比线程切换更大,因为涉及地址空间的转换、
# 6、进程间通信方式有哪些?
管道:
匿名管道:单向通信,只能用于具有亲缘关系的进程间、
- 命名管道:可在任意进程间通信,支持双向数据传输、
信号:
- 通过信号可以向进程发送异步通知,常用于处理异常或特定事件,如终止、暂停进程等
- 常用信号包括
SIGKILL
(强制终止进程)、SIGINT
(中断)等
信号量:
- 用于解决多个进程对共享资源的同步问题、信号量是一个计数器,常用于实现资源的互斥访问、
消息队列:
- 提供了一种将消息存储在队列中的机制,进程可以异步地发送或接收消息
- 消息队列可以实现不同优先级的消息处理,但存在系统对消息队列大小的限制、
共享内存:
- 多个进程可以共享同一块内存区域,是最快的 IPC 方式、
- 需要通过同步机制(如信号量)来确保数据的一致性、
Socket:
- 支持跨网络进程间通信,允许不同主机的进程间进行双向数据传输、
优缺点总结:
管道:简单,但仅限于单向或双向通信,且受限于父子进程、
Socket:适用于跨网络通信,但性能不如共享内存、
消息队列:支持复杂消息传递,但容量受限、
信号量:只能用于同步控制,无法传递复杂数据、
共享内存:速度快,但需要严格的同步控制、
# 7、什么是临界区,如何解决冲突?
临界区是指进程中访问共享资源的代码块
为了防止多个进程同时访问同一共享资源,需要采用同步机制
① 只有一个进程可以进入临界区,其他进程必须等待、
② 每个进程应在有限时间内退出临界区、
③ 如果进程无法进入临界区,则应让出 CPU 以避免忙等、
解决临界区冲突的常见方法包括使用互斥量、信号量等同步机制,确保对共享资源的安全访问、
# 8、什么是死锁?死锁产生的条件?
死锁是指两个或多个进程相互持有资源并等待其他进程释放它们的资源,从而导致各个进程无法继续执行的现象
死锁使得一组进程陷入相互等待的状态,无法进行下一步操作
死锁产生的四个必要条件:
互斥条件:某些资源一次只能被一个进程占用、
请求与保持条件:进程已经持有某些资源,同时请求其他资源,但不释放已持有的资源、
不剥夺条件:进程获得的资源在使用完之前,不能被强行剥夺、
循环等待条件:多个进程形成一种环形等待资源的关系,每个进程都等待下一个进程释放资源、
- 死锁的处理策略:
死锁预防:
- 通过设计确保死锁产生的四个条件中至少一个不成立、
- 例如,不允许进程同时持有资源并请求新资源,或者要求进程按一定顺序请求资源、
死锁避免:
- 动态检测系统的资源分配状态,确保不会进入死锁状态、
- 常用的算法是银行家算法,它通过检查系统是否处于安全状态来避免死锁、
死锁检测与解除:
- 允许死锁发生,但定期检测系统是否进入死锁状态、
- 一旦检测到死锁,可以通过终止进程或回收资源来解除死锁、
鸵鸟策略:
- 对于死锁发生的概率很低或者影响不大的系统,可以选择忽略死锁问题,等待系统管理员手动干预、
# 9、进程调度策略有哪几种?
先来先服务(FCFS):
- 按请求顺序调度进程
- 简单实现,但可能导致短作业等待长作业完成,影响系统响应速度、
短作业优先(SJF):
- 优先调度执行时间最短的进程
- 提高吞吐量,但可能导致长作业饥饿、
最短剩余时间优先(SRTF):
- SJF的抢占式版本,优先调度剩余执行时间最短的进程、
- 当新进程到达时,如果其预期执行时间更短,会抢占当前运行的进程、
时间片轮转(Round Robin, RR):
- 为每个进程分配一个固定的时间片,时间片用完时调度下一个进程、
- 公平性强,但频繁的进程切换可能导致系统开销增大、
优先级调度:
- 根据进程的优先级进行调度,优先级高的进程优先执行、
- 需防止低优先级进程饥饿,通常通过动态提升优先级来避免这一问题、
# 10、进程有哪些状态?
进程通常有五种状态,分别是:创建、就绪、运行、阻塞、终止、
- 创建状态:进程正在被创建,系统为其分配资源,但尚未加入就绪队列、
- 就绪状态:进程获得了除CPU之外的所有必要资源,处于等待调度的状态、
- 运行状态:进程正在CPU上执行,在单处理器系统中,每次只能有一个进程处于运行状态、
- 阻塞状态:进程由于等待某些事件(如I/O操作或资源的释放)而暂停执行,即使CPU空闲,进程也无法运行、
- 终止状态:进程执行结束,系统将释放其所有资源、
状态转换:
- 运行 → 阻塞:当进程等待外部事件或资源(如I/O完成)时,进入阻塞状态、
- 阻塞 → 就绪:等待的事件发生后,进程重新进入就绪状态,等待CPU调度、
- 运行 → 就绪:如果时间片用完或有更高优先级的进程进入,当前进程被切换回就绪状态、
- 就绪 → 运行:调度程序选择一个就绪进程进入运行状态、