死锁出现的必要条件
- 持有并等待:进程至少持有一个资源,并正在等待其他进程持有的资源
- 互斥:任何时刻只有一个进程使用一个资源实例
- 非抢占:资源只能在进程使用后资源释放
- 循环等待:存在一个循环等待的集合
- 如p0 等p1
- p1等p2
- p2等p3
- p3等p0
死锁处理方式
死锁预防
限制资源的申请方式,使系统在任何时刻都不满足死锁的必要条件。(任意使一个条件不满足)
- 取消互斥
- 进程申请资源时,必须一次性将所有(用到的)资源申请
- 资源利用效率低
- 抢占
- 如果进程申请不能立即获取的资源,则释放自己已占用的资源
- 相当于车在单行桥上相遇,互相退出桥
- 对资源排序,要求按照顺序申请资源
死锁避免
在分配资源的时候检查,只有确定不会死锁才分配资源。
系统分为:安全、不安全两种状态,其中不安全包括死锁,即在不安全状态下,可能出现死锁,但不是死锁的充分条件。
银行家算法:
- 进程申明最大资源需要数量
- 系统尽可能满足进程需要
进程所需的资源:
- 进程的资源最大需求量Max
- 进程已占有的资源Allocation
- 进程未来需要的资源Need
- Need=Max-Allocation
安全状态判断:
目的:判断将当前资源分配给进程之后,是否可以找到一个安全序列(顺序),将所有资源都释放(即没有死锁)
- 首先找到当前所剩的资源,可以满足某个进程的未来需求,那么可以判定说此进程是确定可以释放所有资源的(确定可以还得起贷款)
- 找到这样一个进程后,可以将这个进程所有的资源都释放(假释放),再继续判断此时是否能满足另外一个进程的未来需求,如果可以,继续将其释放
- 最后可以找到一个序列,按照这个序列分配资源,则系统一直处于安全状态
- 如果找不到这样一个序列,则表示把当前资源分配给这个进程是危险的,是有可能引起死锁的,那么就不分配给他
进程间通信
- 信号
- 如Ctrl+C(中断程序),每个程序编译的时候,会自动加上
- 信号处理:
- 捕获
- 忽略
- 屏蔽
- 信息量小
- 使用流程:
- 注册信号
- 其他进程发送信号
- 调用回调
- 管道:基于内存文件的通信基址
- 进程不知道管道的另一端(间接通信)
- 基本操作:
- read(fd,buffer,nbytes)
- write(fd,buffer,nbytes)
- pipe(rgfd) 创建管道
- 消息队列:由操作系统维护(间接通信)
- 基本操作:
- msgget 获取消息队列标志
- msgsnd
- msgrcv
- msgctl
- 即使创建消息队列的进程消失了,消息队列仍然可以存在
- 共享内存:一段物理空间,映射给多个进程
- 方便快速
- 需外加同步机制