11.1死锁问题
1、死锁现象
出现的原因:进程并发运行
11.2系统模型
1、资源概念
- 资源一旦是被使用状态,则其他的进程就不应该运用这个资源,有互斥性,如果没有互斥性,就不会产生死锁。
- 进程使用资源的有限的,资源恢复到空闲的情况。
2、可重复使用的资源
1)在一个时间只能一个进程使用且不能删除
2)进程获得资源,后来释放有其他进程重用
3)处理器,io通道,主和副存储器,设备和数据结构,如文件,数据库和信号量都可以看作是资源的一种形式
4)如果每个进程拥有一个资源并且请求其他资源,死锁可能发生
3、如何使用资源
1)创建和销毁进行资源管理,内存管理
2)在op缓冲区中的中断,信号,消息,信息
3)如果接受消息阻塞可能会发生死锁
4)可能少见的组合事件会引起死锁
5)存在进程管理和调度的过程
4、资源分配图
pi->rj:表示进程i需要j的资源
rj->pi:表示资源i被j所使用
5、死锁的判断
1)情况一
不会产生死锁
2)情况二
会产生死锁,这个图形成了一个环状的结构(一个大环和小环)
3)情况三
有环状的资源分配图没有死锁
总结:
死锁一定有环,但是有环不一样产生死锁
11.3死锁的特征
这个是死锁出现的四个特征:
需要注意:这四个特征出现并不意味着死锁的出现
右图的p2和p4不满足持有并等待资源,所以不满足这四个特征,所以不是死锁。
11.4死锁处理办法
以上的四个方法的约束一个比一个弱,死锁预防的约束最强,而死锁恢复的约束最差。
方法一:确保系统永远不会进入死锁状态
操作系统的功能会被限制,应用系统无法重复的利用cpu执行开销也很大
方法二:运行系统进入死锁状态,然后恢复
但是判断死锁的开销非常大
方法三:忽略这个问题,假装系统中从来没有发生死锁;用于绝大多数的操作系统。
靠假设来忽略这个问题,实际操作的常用方法
11.5死锁预防和死锁避免
1、死锁的预防 ---- 让死锁不会出现
思路:只要将前诉的四个资源打破其中的一个,那么久不会出现死锁。
针对死锁的四个必要条件,打破死锁进行一开始预防:
1)互斥
本来资源是互斥的,通过使资源不互斥。
2)占用并等待
将条件变大,拿资源就拿全部的资源才去执行,否者不能资源去睡眠,这样就不会存在死锁。但是不同的执行过程中,需要的资源不同,导致一直占用资源但是没有使用,所以会导致系统资源的利用率低。
3)不抢占
直接将进程kill掉,也就将资源抢占过来了,但是手段比较的暴力,不合理。
4)循环等待
死锁的出现会出现一个环,打破这个环可以实现死锁的预防。如果对资源类型进行排序,进程按资源顺序进行申请,也就是资源只能往上进行申请,这样就不会形成循环的圈。但是前提是要讲资源排好序,但是资源利用还是不合理的。
2、死锁避免
比上诉的约束条件放松一点
思路:当进程在申请资源的过程中,然后判断这个申请合不合理,如果会存在死锁的概率,就会拒绝这个请求。
需要注意:
其中,不安全状态不一定对导致死锁状态,所以不安全状态是包含着死锁状态,我们需要的是安全状态。将是否会形成环来作为判断依据。
问题:什么是安全状态?
针对所有的进程,存在一个时间序列,按照这个序列执行,先后顺序执行,所以的进程都可以正常的等待所需要的资源,正常的结束。
要避免进入unsafe空间。而在safe状态不会出现一个环。
11.6银行家算法
一、基础
1、算法的背景
2、前提基础
很重要的判断:safe还是unsafe
二、算法设计
1、数据结构的设计
1)n = 进程数量
2)m = 资源类型数量
(其中,每一个资源类型还要一个量)
3)Max(某种类型的总需求量):nxm矩阵。
如果Max[i,j] = k,表示进程Pi最多请求资源类型Rj的k个示例
(可以知道其整个生命周期中共需要该类多少个资源)
其中存在一条关系式:
2、初始化
3、操作
执行之后:
可申请的资源变少,变少了request
已分配的资源变多,变多了request
还需要的资源变少,变少了request
根据返回值做出改变:
以上就是银行家算法的一个大致思路。
三、示例
第一个例子
1、首先系统和进程所拥有的资源如下图所示
需要注意:
Max:所有进程需要资源的情况
Need:当前进程需要进程的情况
Available:系统还剩下资源的情况
Allocation:当前进程已经拥有的资源
Resource:当前系统中总资源的个数
2、可见,p2可以满足情况,执行后可返回其所占有的资源
3、回收资源之后,按照顺序,p1所需要的资源是可以满足的,可以执行
4、p1执行完之后,对资源进行回收,接下来剩下的两个进程偶读可以满足要求。可以随便选一个,比如p3,然后再选择p4.
结论:
所以,这样我们就已经找到了一个序列,如果按照p2-p1-p3-p4这个顺序去执行,就可以实现所以的进程都可以正常的执行并结束,其所需要的资源都可以得到满足。这个就是安全的执行序列,safe。
第二个例子:
如果一开始p1提出了一个101请求,执行之后
此时系统所剩余的资源为011,此时不能满足任何的其他进程,会进入一个unsafe的状态。
所以,一开始银行家算法是不会接受p1的101的请求的。
总结:
银行家算法的思路是判断当前的资源分配操作是否安全的,如果安全则可以执行,如果不安全就不能分配出去。
11.7死锁检测和死锁恢复
一、基础
1、背景
- 死锁的检测又将条件放宽了一点。
- 前面的死锁避免是既是不会导致死锁的现象方法,但是如果会出现不安全状态,也不会执行。
这里的死锁检测允许系统进入unsafe状态,在某一个状态判断当前的系统是否出现死锁,如果是,就启动恢复机制;如果没有,就继续执行,将死锁的检测放在了系统运行中,更往后了。
2、死锁检测的大致思路
- 允许系统进入死锁状态
- 死锁检测算法
- 恢复机制
3、检测原理
1)将资源分配图中资源的节点简化,只留下进程。从而将资源分配图,变成进程等待图。然后再判断这个等待图是否具有环。有环就代表有可能死锁。
2)死锁检测算法
死锁检测算法,定期的执行对操作系统运行比较大,更多是起调试的作用。而已银行家算法需要提前知道进程未来所需要的资源,这个是比较难实现的,只能去预估。
二、示例
1、例子一
2、例子二
结果:
没有一个进程的需求可以得到满足,死锁会检测出一个环,与银行家算法是比较类似的。
三、算法是使用
四、死锁的恢复
都存在某种程度上的强制性和不合理性。所以死锁恢复是最后的手段。
11.8IPC概述
一、基础
IPC的意思就是进程间通信
1、问题:为什么要进行进程间通信?
进程之间可能要完成一个大的任务,这需要一定的数据的沟通和信息的传递,保存进程独立性的通信,保证其可以有效的沟通。
2、IPC提供2个操作
send message
receive message
3、通信的前提
在他们之间建立通信链路
通过send/receive交换消息
4、通信链路实现
物理(例如共享内存,硬件总线)
逻辑(例如,逻辑属性)
二、间接通信与直接通信
1)直接通信
2)间接通信
主需要关注在哪里收数据或者将数据丢到哪里去就行了。一般是os中的共享数据。
三、阻塞或是非阻塞的
11.9信号,管道,消息队列和共享内存
(这里只是作简单的介绍,没有涉及具体的实现方法)
1、数据的缓冲
需要注意:
无论是哪种情况,当缓冲中没有数据的时候,接收方都必须等待数据的到来
一、信号
1、介绍
关注某一种信号,发生了某一种响应之后,可以编写特定的处理函数。效率比较高。
处理完之后,会回到被打断的函数重新的实现。
2、如何实现
应用程序针对某种新号作定点处理,要完成的操作是:
1)开始的时候,要针对某种信号的handle,把这个作为系统调用发给操作系统。操作系统就知道当这个进程发出某种信号就会跳转到预先编写的处理函数中。
2) 操作系统将系统调用返回用户空间的堆栈进行修改,使得本来是返回调用语句的后条执行变成到这个信号处理函数的入口,同时在把信号处理函数的之后的地址作为栈帧的返回地址。所以要修改应用程序的堆栈。
二、管道
管道是用来实现数据的交换。其以文件的操作。
思路:将一个文件的输出,重定向到令一个文件的输入,这样就可以完成一系列的操作。(重定向符为“>”)
如何实现:
shell进程收到了这条命令之后,会创建两个进程,ls进程和more进程。同时将ls的输出到一个管道中,而不是屏幕上(内存中的一个buffer)。而对于more,不是从键盘接受信息,而是从管道中接受数据,这样就完成了输入输出的重定向功能。这样就完成了分页显示目录的功能。(存在阻塞现象)
特点:
1)管道是通过父进程帮子进程建立好的一个通道,如果没有父子关系,这样就不能正常工作了。
2)管道的数据是一种字节流。
3)有bufffer满和buffer空的限制
三、消息队列
特点:
1)数据是结构化的数据,而不是字节流,传进去的是一个有意义的数据结构
2)可以实现多个互不相关的进程完成数据交换
四、共享内存
上面两种都是间接通信。共享内存是直接通信的方式。
(通过内核,读写内存,实现进程的数据的交换)
共享内存的实现机制: