死锁

第11章:死锁和进程通信


  • 死锁概念
  • 死锁处理方法
  • 死锁预防(Deadlock Prevention)
  • 死锁避免(Deadlock Avoidance)
  • 死锁检测和恢复(Deadlock Detection & Recovery)
  • 死锁检测和恢复(Deadlock Detection & Recovery)
  • 由应用进程处理死锁
  • 银行家算法
  • 死锁检测
  • 进程和通信概念
  • 信号和管道
  • 消息队列和共享内存

11.1 死锁概念

  • defs:死锁是进程之间由于共享资源所导致的一种无限期等待的情况

    • 由于竞争资源或者通信关系,两个或更多线程在执行中出现永远相互等待,只能由其他进程引发的事件

进程访问资源的流程

  • 资源类型R1,R2,…,Rm

    • CPU执行时间,内存空间,I/O设备等
  • 每类资源Ri有Wi个实例

  • 进程访问资源的流程

    • 请求/获取

      • 申请空闲资源
    • 使用/占用

      • 进程占用资源
    • 释放

      • 资源状态由占用变成空闲

资源分类

  • 可重用资源(Reusable Resource)

    • 资源不能被删除且在任何时刻只能有一个进程使用

    • 进程释放资源后,其他进程可重用

    • 可重用资源示例

      • 硬件:处理器、I/O通道、主和副存储器、设备等
      • 软件:文件、数据库和信号量等数据结构
    • 可能出现死锁

      • 每个进程应用一部分资源并请求其他资源
  • 消耗资源(Consumable resource)

    • 资源创建和销毁

    • 资源消耗示例

      • 在I/O缓冲区的中断、信号和消息等
    • 可能会出现死锁

      • 进程间相互等待接收对方的消息

出现死锁的必要条件

  • 互斥

    • 任何时刻只能有一个进程使用一个资源实例
  • 持有并等待

    • 进程保持至少一个资源,并正在等待获取其他进程特有的资源
  • 非抢占

    • 资源只能在进程使用后自愿释放
  • 循环等待

11.2 死锁处理方法

  • 死锁预防(Deadlock Prevention)

    • 确保系统永远不会进入死锁状态
  • 死锁避免(Deadlock Avoidance)

    • 在使用前进行判断,只允许不会出现死锁的进程请求资源
  • 死锁检测和恢复(Deadlock Detection & Recovery)

    • 在检测到运行系统进入死锁状态后,进行恢复
  • 由应用进程处理死锁

    • 通常操作系统忽略死锁

      • 大多数操作系统(包括UNIX)的做法

(一)死锁预防:限制申请方式

  • 预防是采用某种策略,限制并发进程对资源的请求,使系统在任何时刻都不满足死锁的必要条件

  • 互斥

    • 把互斥的共享资源封装成可同时访问
  • 持有并等待

    • 进程请求资源时,要求它不持有任何其他资源
    • 仅允许进程在开始执行时,一次请求所有需要的资源
    • 资源利用率低
  • 非抢占

    • 如进程请求不能立即分配的资源,则释放已有资源
    • 只在能够同时获得所有需要资源时,才执行分配操作
  • 循环等待

    • 对资源排序,要求进程按顺序请求资源

(二)死锁避免

  • 利用额外的先验信息,在分配资源时判断是否会出现死锁,只在不会死锁时分配资源

    • 要求进程声明需要资源的最大数目
    • 限定提供与分配的资源数量,确保满足进程的最大需求
    • 动态检查资源分配状态,确保不会出现环形等待

系统资源分配的安全状态

  • 当进程请求资源时,系统判断分配后是否处于安全状态

  • 系统处于安全状态

    • 针对所有已占用进程,存在安全序列
  • 序列

安全状态与死锁的关系

  • 系统处于安全状态,一定没有死锁

  • 系统处于不安全状态,可能出现死锁

    • 避免死锁就是确保系统不会进入不安全状态

11.3 银行家算法

  • 银行家算法是一个避免死锁产生的算法,以银行借贷发配策略为基础,判断并保证系统处于安全状态

银行家算法:数据结构

  • n = 线程数量, m = 资源类型数量

  • Max(总需求量):n×m矩阵

    • 线程Ti最多请求类型Rj的资源 Max[i,j]个实例
  • Available(剩余空闲量):长度为m的向量

    • 当前有Available[i]个类型Rj的资源实例可用
  • Allocation(已分配量):n×m矩阵

    • 线程Ti当前分配了 Allocation[i,j]个Rj的实例
  • Need(未来需要量):n×m矩阵

    • 线程Ti未来需要Need[i,j]个Rj资源实例
  • Need[i,j] = Max[i,j] - Allocation[i,j]

银行家算法:安全状态判断

1. Work 和 Finish 分别是长度为m和n的向量初始化:
    Work = Available //当前资源剩余空闲量
    Finish[i] = false for i:1,2,...,n //线程i没结束
2. 寻找线程Ti:
    (a)Finish[i] = false //接下来找出Need比Work小的线程i 
    (b) Need[i] <= Work
    没有找到满足的条件Ti,转4
3. Work = Work + Allocation[i] //线程i的资源需求量小于当前剩余空闲资源量,所以配置给它再回收
    Finish[i] = true
    转2
4. 如所有线程Ti满足Finish[i] == true,则系统处于安全状态 //所有线程的Finish为True,表明系统处于安全状态

银行家算法

初始化:Requesti 线程Ti的资源请求向量
        Requesti [j] 线程Ti请求资源Rj的实例

循环:
1\. 如果Requesti <= Need[i],转到2。否则拒绝资源申请,因为线程已经超过了其最大要求
2\. 如果Requesti <= Available,转到3。否则,Ti必须等待,因为资源不可用
3\. 通过安全状态来确定是否分配资源给Ti:
    生成一个需要判断状态是否安全的资源分配环境
        Available = Available - Requesti;
        Allocation[i] = Allocation[i] + Requesti;
        Need[i] = Need[i] - Requesti;
    调用安全状态判断
        如果返回结果是安全,将资源分配给Ti
        如果返回结果不安全,系统会拒绝Ti的资源请求

11.4 死锁检测

  • 允许系统进入死锁状态
  • 维护系统的资源分配图
  • 定期调用死锁检测算法来搜索图中是否存在死锁
  • 出现死锁时,用死锁恢复机制进行恢复

死锁检测:数据结构

  • Available:长度为m的向量

    • 每种类型可用资源的数量
  • Allocation:一个 n×m矩阵

    • 当前分配给各个进程每种类型资源的数量
    • 进程Pi拥有资源Rj的Allocation[i,j]个实例

死锁检测算法

1. Work 和 Finish 分别是长度为m和n的向量初始化:
    Work = Available //Work为当前资源剩余空闲量
    Allocation[i] > 0 时,Finish[i] = false //finish为线程是否结束
    否则,Finish[i] = true
2. 寻找线程Ti满足:
    (a)Finish[i] = false //寻找没有结束的线程,且此线程将需要的资源量小于当前空闲资源量
    (b) Requesti <= Work
    没有找到满足的条件Ti,转4
3. Work = Work + Allocation[i] //把找到的线程拥有的资源释放回当前空闲资源中
    Finish[i] = true
    转2
4. 如某个 Finish[i] == false,则系统处于死锁状态 //如果有Finish为false,表明系统处于死锁状态
  • 算法需要O(m×n^2)操作检测是否系统处于死锁状态

死锁检测算法的使用

  • 死锁检测的时间和周期选择依据

    • 死锁多久可能会发生
    • 多少进程需要回滚
  • 资源可能有多个循环

    • 难于分辨“造成”死锁的关键进程

死锁恢复:进程终止

  • 终止所有的死锁进程

  • 一次只终止一个进程直到死锁消除

  • 终止进程的顺序应该是

    • 进程的优先级(由低到高)
    • 进程已运行时间以及还需运行时间(保留运行时间较长者)
    • 进程已占用资源
    • 进程完成需要的资源
    • 终止进程数目(越少越好)
    • 进程是交互还是批处理(优先让用户交互的进程执行下去)

死锁恢复:资源抢占

  • 选择被抢占进程

    • 最小成本目标
  • 进程回退

    • 返回到一些安全状态,重启进程到安全状态
  • 可能出现饥饿

    • 同一进程可能一直被选择被抢占者

11.5 进程通信概念

进程通信(IPC, Inter-Process Communication)

  • 进程通信是进程进行通信和同步的机制

  • IPC提供两个基本操作

    • 发送操作:send(message)
    • 接收操作:receive(message)
  • 进程通信流程

    • 在通信进程间建立通信链路
    • 通过send/receive交换信息
  • 进程链路特征

    • 物理(如,共享内存、硬件总线)
    • 逻辑(如,逻辑属性)

直接通信

  • 进程必须正确的命名对方

    • send(P, message) - 发送信息到进程P
    • receive(Q, message) - 从进程Q接收信息
  • 通信链路属性

    • 自动建立链路
    • 一条链路恰好对应一对通信进程
    • 每对进程之间只有一个链接存在
    • 链接可以是单向的,但通常是双向的

间接通信

  • 通过操作系统维护的消息队列实现进程间的消息接收和发送

    • 每个消息队列都有一个唯一的标识
    • 只有共享了相同的消息队列的进程,才能够通信
  • 通信链路的属性

    • 只有共享了相同的消息队列的进程,才建立连接
    • 连接可以是单向或双向
    • 消息队列可以与多个进程相关联
    • 每对进程可以共享多个消息队列
  • 通信流程

    • 创建一个新的消息队列
    • 通过消息队列发送和接收消息
    • 销毁消息队列
  • 基本通信操作

    • send(A, message) - 发送消息到队列A
    • receive(A, message) - 从队列A接收消息

阻塞与非阻塞通信

  • 进程通信可划分为阻塞(同步)或非阻塞(异步)

  • 阻塞通信

    • 阻塞发送

      • 发送者在发送消息后进入等待,直到接收者成功收到
    • 阻塞接收

      • 接收者在请求接收消息后进入等待,直到成功收到一个消息
  • 非阻塞通信

    • 非阻塞发送

      • 发送者在消息发送后,可立即进行其他操作
    • 非阻塞接收

      • 没有消息发送时,接收者在请求接收消息后,接收不到任何消息

通信链路缓冲

  • 进程发送的消息在链路上可能有3种缓冲方式

    • 0容量

      • 发送方必须等待接收方
    • 有限容量

      • 通信链路缓冲队列满时,发送方必须等待
    • 无限容量

      • 发送方不需要等待

11.6 信号量和管道

(一)信号

信号

  • 进程间的软件中断通知和处理机制
  • 如,SIGKILL, SIGSTOP, SIGCONT等

信号的接收处理

  • 捕获(Catch)

    • 执行进程指定的信号处理函数被调用
  • 忽略(Ignore)

    • 执行操作系统指定的缺省处理

      • 例如:进程终止、进程挂起等
  • 屏蔽(Mask)

    • 禁止进程接收和处理信号

      • 可能是暂时的(处理同种类型的信号)

不足

  • 传送的信息量小,只有一个信号类型

(二)管道

管道(pipe)

  • 进程间基于内存文件的通信机制

    • 子进程从父进程继承文件描述符
    • 缺省文件描述符:0 stdin , 1 stdout, 2 strerr
  • 进程不知道(或不关心)另一端

  • 可能从键盘、文件、程序读取

  • 可能写入到终端、文件、程序

与管道相关的系统调用

  • 读管道:read(fd, buffer, nbytes)

    • scanf()是基于它实现的
  • 创建管道:pipe(rgfd)

    • rgfd是2个文件描述符组成的数组

      • rgfd[0]是读文件描述符
      • rgfd[1]是写文件描述符

11.7 消息队列和共享内存

(一)消息队列

  • 消息队列是由操作系统维护的以字节序列为基本单位的间接通信机制

    • 每个消息(message)是一个字节序列
    • 相同标识的消息按先进先出顺序组成一个消息队列(Message Queues)

消息队列的系统调用

  • msgget(QID, buf, size, flags)

    • 发送消息
  • msgrcv(QID, buf, size, type, flags)

    • 接收消息
  • msgctl(…)

    • 消息队列控制

(二)共享内存

  • 共享内存是把同一个物理内存区域同时映射到多个进程的内存地址空间的通信机制

进程

  • 每个进程都有私有地址内存空间
  • 每个进程的内存地址空间需要明确设置于共享内存段

线程

  • 同一进程中的线程总是共享相同的内存地址空间

优点

  • 快速、方便的共享数据

不足

  • 必须用额外的同步机制来协调数据访问

特点

  • 最快的方法

  • 一个进程写另一个进程立即可见

  • 没有系统调用干预

  • 没有数据复制

  • 不提供同步

    • 由程序员提供同步

共享内存的系统调用

  • shmget(key, size, flags)

    • 创建共享段
  • shmat(shmid, *shmaddr, flags)

    • 把共享段映射到进程地址空间
  • shmdt(*shmaddr)

    • 取消共享段到进程地址空间的映射
  • shmctl(…)

    • 共享段控制
  • 完成共享关系的建立,而正常共享数据的访问只需读写指令,不需要专门的系统调用

  • 需要信号量等机制协调共享内存的访问冲突

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,227评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,755评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,899评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,257评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,617评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,757评论 1 221
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,982评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,715评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,454评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,666评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,148评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,512评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,156评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,112评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,896评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,809评论 2 279
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,691评论 2 272

推荐阅读更多精彩内容

  • 20.1死锁概念 由于竞争资源或者通信关系,两个或更多线程在执行中出现,永远相互等待只能由其他进程引发的事件 进程...
    龟龟51阅读 607评论 0 1
  • 1、竞态条件: 定义:竞态条件指的是一种特殊的情况,在这种情况下各个执行单元以一种没有逻辑的顺序执行动作,从而导致...
    Hughman阅读 1,218评论 0 7
  • 1. 基础知识 1.1、 基本概念、 功能 冯诺伊曼体系结构1、计算机处理的数据和指令一律用二进制数表示2、顺序执...
    yunpiao阅读 5,115评论 1 22
  • 上个月加入007不出局,在111班级做小组长,班长赠送了我一本书, 《被讨厌的勇气》 这周每天一点点终于读完了。...
    刘伟节123阅读 635评论 0 4
  • 房价大概是眼下每个中国人都绕不开的话题。北京的楼市对我影响很大,抛开买得起买不起这个沉重的话题,楼市对我影响最大的...
    我叫杨土地阅读 218评论 0 0