操作系统(11)—— 死锁与进程间通信

一、系统模型

1、资源概念

  • 资源一旦是被使用状态,则其他的进程就不应该运用这个资源,有互斥性,如果没有互斥性,就不会产生死锁。
  • 进程使用资源的有限的,资源恢复到空闲的情况。
2. 可重复使用的资源
  • 在一个时间只能一个进程使用且不能删除
  • 进程获得资源,后来释放有其他进程重用
  • 处理器,io通道,主和副存储器,设备和数据结构,如文件,数据库和信号量都可以看作是资源的一种形式
  • 如果每个进程拥有一个资源并且请求其他资源,死锁可能发生
3. 如何使用资源
  • 创建和销毁,进行资源管理,内存管理
  • 在I/O缓冲区中的中断,信号,消息,信息
  • 如果接收消息阻塞可能会发生死锁
  • 可能少见的组合事件会引起死锁
  • 存在进程管理和调度的过程

二、死锁的特征及处理办法

1. 死锁的特征

死锁可能出现如果四个条件同时成立:

  • 互斥:在一个时间只能有一个进程使用资源
  • 持有并等待:进程保持至少一个资源正在等待获取其他进程持有的额外资源
  • 无抢占:一个资源只能被进程自愿释放
  • 循环等待:存在等待进程集合,一个等待另一个占用的资源,首尾相接(有环)。

出现这四个条件不一定出现死锁,但是死锁肯定会出现这四个条件。

2. 死锁处理办法

方法一:确保系统永远不会进入死锁状态

  • 操作系统的功能会被限制,应用系统无法重复的利用cpu执行开销也很大

方法二:运行系统进入死锁状态,然后恢复

  • 但是判断死锁的开销非常大

方法三:忽略这个问题,假装系统中从来没有发生死锁;用于绝大多数的操作系统。

  • 靠假设来忽略这个问题,实际操作的常用方法

包括以下四种方法:

  • 死锁预防
  • 死锁避免
  • 死锁检测
  • 死锁恢复

以上的四个方法的约束一个比一个弱,死锁预防的约束最强,而死锁恢复的约束最差。

三、死锁预防和死锁避免

1. 死锁预防——让死锁不会出现

思路:只要将之前所说的四个必要条件打破其中的一个,就不会出现死锁。

针对死锁的四个必要条件,打破死锁进行一开始预防:

  • 互斥:共享资源不是必须的,必须占用非共享资源。即本来资源是互斥的,通过使资源不互斥。

  • 占用并等待:必须保证当一个进程请求的资源,它不持有其他任何资源。

    • 将条件变大,拿资源就拿全部的资源才去执行,否则不能资源去睡眠,这样就不会存在死锁。但是不同的

      执行过程中,需要的资源不同,导致一直占用资源但是没有使用,所以会导致系统资源的利用率低。

  • 不抢占:直接将进程kill掉,也就将资源抢占过来了,但是手段暴力,不合理。

  • 循环等待:对所有资源类型进行排序,并要求每个进程按照资源的顺序进行申请。

    • 死锁的出现会出现一个环,打破这个环可以实现死锁的预防。如果对资源类型进行排序,要求进程按资源

      顺序进行申请,也就是资源只能往上进行申请,这样就不会形成循环的圈。但是前提是要讲资源排好序,

      但是资源利用还是不合理的。

2. 死锁避免

思路:当进程在申请资源的过程中,然后判断这个申请合不合理,如果会存在死锁的概率,就会拒绝这个请求。

需要系统具有一些额外的先验信息提供:

  • 最简单和最有效的模式是要求每个进程声明它可能需要的每个类型资源的最大数目
  • 资源的分配状态是 通过限定提供与分配的资源数量和进程的最大需求
  • 死锁避免算法动态检查的资源分配状态,以确保永远不会有一个环形等待状态。

当一个进程请求可用资源,系统必须立即分配是否能使系统处于安全状态。

  • 处于安全状态:针对所有进程,存在安全序列(按照这个序列执行,先后顺序执行,所以的进程都可以正常的等待所需要的资源,正常的结束)。

死锁避免:确保系统永远不会处于非安全状态。

四、死锁检测和死锁恢复

1. 死锁检测

​ 死锁检测允许系统进入unsafe状态,在某一个状态判断当前的系统是否出现死锁,如果是,就启动恢复机制;如果没有,就继续执行,将死锁的检测放在了系统运行中,更往后了。

死锁检测的大致思路
  • 允许系统进入死锁状态
  • 死锁检测算法
  • 恢复机制

检测原理:定期的检测是否有环存在。

定期的执行对操作系统运行比较大,更多是起调试的作用。

2. 死锁的恢复
  • 终止所有的死锁进程
  • 在一个时间内终止一个进程直到死锁消除
  • 终止进程的顺序应该是
    • 进程的优先级
    • 进程运行了多久以及需要多少时间才能完成
    • 进程占用的资源
    • 进程完成需要的资源
    • 多少进程需要被终止
    • 进程是交互还是批处理

都存在某种程度上的强制性和不合理性。所以死锁恢复是最后的手段。

五、进程间通信(IPC,Inter Processes Communication)

1. 问题:为什么要进行进程间通信?
  • 进程之间可能要完成一个大的任务,这需要一定的数据的沟通和信息的传递,保存进程独立性的通信,保证其可以有效的沟通。
2. IPC提供2个操作
  • send message
  • receive message
3. 通信的前提
  • 在他们之间建立通信链路
  • 通过send/receive交换消息
4. 通信链路实现
  • 物理(例如共享内存,硬件总线)
  • 逻辑(例如,逻辑属性)

六、信号,管道,消息队列和共享内存

1. 数据的缓冲

队列的消息被附加到链路;可以是以下3种方式之一:

  • 0容量- 0 messages

    发送方必须等待接收方(rendezvous)

  • 有限容量-n messages的有限长度

    发送方必须等待,如果队列满

  • 无限容量一无限长度

    发送方不需要等待

2. 信号:软件中断通知事件处理

接收到信号时会发生什么

  • Catch:指定信号处理函数被调用

  • Ignore: 依靠操作系统的默认操作

  • Mask: 闭塞信号因此不会传送

    可能是暂时的(当处理同样类型的信号)

不足:不能传输要交换的任何数据

关注某一种信号,发生了某一种响应之后,可以编写特定的处理函数。效率比较高。 处理完之后,会回到被打断的函数重新的实现。

3. 管道:用来实现数据的交换。文件的操作。
  • 思路:将一个文件的输出,重定向到令一个文件的输入,这样就可以完成一系列的操作。(重定向符为“>”)

  • 实现:shell进程收到一条命令之后,会创建两个进程,ls进程和more进程。同时将ls的输出到一个管道中,

    而不是屏幕上(内存中的一个buffer)。而对于more,不是从键盘接受信息,而是从管道中接受数据,这样

    就完成了输入输出的重定向功能。这样就完成了分页显示目录的功能。(存在阻塞现象)

  • 特点:

    • 管道是通过父进程帮子进程建立好的一个通道,如果没有父子关系,这样就不能正常工作了。
    • 管道的数据是一种字节流。
    • 有bufffer满和buffer空的限制。
4. 消息队列:按照FIFO来管理消息

特点:

  • 数据是结构化的数据,而不是字节流,传进去的是一个有意义的数据结构;
  • 可以实现多个互不相关的进程完成数据交换 。
5. 共享内存

上面两种都是间接通信。共享内存是直接通信的方式。(通过内核,读写内存,实现进程的数据的交换)

  • 进程

    • 每个进程都有私有地址空间
    • 在每个地址空间内,明确地设置了共享内存段
  • 优点:快速、方便地共享数据

    不足:必须同步数据访问

你可能感兴趣的:(操作系统)