多进程死锁:多进程中,等待进程所申请的资源被其他等待进程持有,那么该等待进程有可能永远都无法改变状态。
资源分类:资源类型有很多,如cpu周期,文件,IO设备等。
资源实例:资源类型的一个实体,如系统具有两个cpu,那么cpu资源就有两个实例。
相同实例:如果进程请求某个类型的资源实例,而分配任意一个该资源类型的实例都能满足要求,称这些实例是相同的。否则这些实例就不相同,如打印机A和打印机B在不同地点,如果只是申请打印文件而不关心打印机的位置,那么这两个资源实例是相同的,而如果关心打印机的位置,那么地点就很重要,而这两台打印机就不是相同的资源实例。
同步工具:如互斥锁,信号量等,也应作为系统资源,它们是常见的死锁源。
进程在使用资源前要申请,使用完资源后要释放资源,一个进程可能要申请许多资源,但是申请的资源不能超过系统提供资源的总和。
使用资源的顺序:
1.申请:进程申请使用资源,如果申请不能被立即执行,那么申请进程应等待,直到它获得申请的资源。
2.使用:进程使用资源进行操作。
3.释放:进程释放资源。
死锁产生的必要条件:(同时成立则引起死锁)
1.互斥:至少一个资源必须处于非共享模式,即一次只有一个进程可以使用该资源。
2.占有并等待:一个进程至少占有一个资源并处于等待其他资源,而其他资源被其他进程占有。
3. 非抢占:资源不能被抢占。只要资源被一个进程获得,那么直到它将一直拥有该资源直到它主动释放该资源。
4.循环等待:一组资源中,占有并等待资源形成循环,如p1占有资源r1等待资源r2而p2占有r2,等待r3,r3占有r3等待r1,如此形成占有并等待的循环。循环等待与占有并等待不独立。
用有向图的方式描述系统的资源分配。节点分为进程节点Pi和资源节点Ri。进程节点向资源节点的边称为申请边,意为进程Pi申请资源Ri,资源节点向进程节点的边称为分配边,意为资源Ri已经分配给进程Pi。当申请被允许时,申请边转换为分配边,当资源被释放时,分配边从图中删除。
如果图中没有环,那么进程一定不存在死锁。如果图中有环,那么可能产生死锁。图中有环产生死锁的条件是,环中的每个资源只有一个实例。因此资源分配图中有环,是死锁的必要条件。
如果图中每个资源只有一个实例,图中又有环,那么一定产生死锁。同理,如果图中有环,环中的每个资源只有一个实例,也必然产生死锁。
死锁处理方法主要分为:
1. 通过协议来预防或避免死锁,确保系统不会进入死锁状态。
2. 运行系统进入死锁状态, 但是检测死锁,并恢复。
3. 忽视这个问题,认为系统中不可能发生死锁。应用程序的开发者需要自己编写程序,来处理死锁问题。大多数操作系统都采用第三种方法。
死锁预防:方法保证死锁产生的必要条件中至少有一个不成立,这样死锁就不会产生。
死锁避免:操作系统事先得到进程申请资源和获取资源的额外信息,这样,系统在保证不会产生死锁的前提下,确定进程是否应该等待。
死锁恢复:系统提供算法来检测死锁,并进行恢复。
死锁处理的经济性:如果死锁出现不频繁,甚至一年出现一次,那么增加大量的代码来进行死锁处理是不经济的,这种情况下应该允许死锁的出现,并且不进行检测和恢复,而是让人工来重启系统等操作。
死锁产生必须同时满足四个条件,因此只要其中一个条件被破坏,那么死锁就不会出现。死锁预防因此也分为四种:
1.互斥:破坏互斥条件,如共享只读文件,多个进程同时打开一个只读文件,那么他们可以同时访问,而不需要等待资源。但是改变互斥条件不能解决所有的死锁问题,因为有的资源本身就是非共享的,如互斥锁。
2.持有且等待:破坏持有且等待条件,保证一个进程在等待其他资源时,不能占有资源。因此一种协议是,只有当进程可以获得所有申请的资源时,才一次性分配给它所需的资源。另一种协议是,进程只有在没有持有资源时,才可以申请资源。
破坏持有且等待的缺点:1.资源利用率比较低,许多资源可能已分配,但是长时间没有被使用,如果进程所需的资源中,其中一个非常耗时,那么剩余的资源被分配给这个进程,却一直没有被使用。2.可能发生饥饿。一个进程如果需要很多资源,而其中一项已分配给其他进程,那么它将必须等待。
3.非抢占:破坏非抢占条件。将非抢占修改为:如果一个进程申请的资源不可用,在它等待该资源时,它所持有的资源都可以被其他进程抢占。
4.循环等待条件:破坏循环等待条件。对所有资源进行排序,要求每个进程按照递增顺序来申请资源。将资源类型映射到整数,Ri->N,如果要申请多个不同类型资源,那么必须按照N递增的顺序来申请。如磁带驱动器为3,打印机为5。如果一个进程需要申请这两个资源,那么它必须先申请磁带驱动器,再申请打印机。另外,进程申请资源Ri时,它必须先释放所有的资源Rj(F(Rj)>F(Ri)),即释放所有比申请资源的映射数字大的资源。如果要申请同一个资源的多个实例,那么必须同时申请。
死锁避免不破坏死锁产生的必要条件,而是通过其他额外信息,即如何申请资源,来避免死锁的产生。如要求进程声明可能需要的每种类型资源的最大数量,设计死锁避免算法。死锁避免算法动态检测资源分配状态,以确保循环等待条件不会成立。资源分配状态包括:可用的资源,已分配的资源及进程的最大要求。
实现死锁避免的算法有:安全状态算法,银行家算法,
如果系统能按一定顺序为进分配资源,却仍然避免死锁,那么系统是安全的。即只有存在一个安全序列,系统才是安全的。算法在每次分配资源时,检查是否存在安全序列,如果存在,那么进程等待。这种方法会降低资源使用率。
安全序列:进程序列{Pi}是安全序列是指,对于每个进程Pi,Pi可以申请的资源+所有其他进程Pj所占有的资源之和小于系统最大资源。
如果系统每个类型的资源都只有一个实例,那么就可以使用资源分配图的形式来判断是否发生死锁。如果每个类型的资源有超过一个实例,那么可以用资源分配图判断安全状态。在资源分配图中,如果系统允许进程的资源申请,那么资源申请边将会变成资源分配边。如果一个资源申请边变为资源分配边后,资源分配图中有环,那么说明给进程分配该资源会让系统进入非安全状态,此时不应给进程分配资源,而应让进程等待。
当一个进程进入系统时,它声明可能需要的每种类型资源实例的最大数目,这一数目不能超过系统资源总和。当用户申请一组资源时,系统检查这些资源分配后,系统是否仍处于安全状态,如果会,就分配资源,否则进程必须等待,直到分配后系统仍处于安全状态。
如果每中类型资源只有一个实例,那么可以使用资源分配图的一个变形,称为等待图来检测死锁。应用死锁检测的时机取决于:死锁发生的频率和死锁发生时有多少进程受影响。
当检测到死锁发生后,有两种选择,一是通知操作员,手动处理死锁。二是让系统从死锁中自动恢复。打破死锁有两种选择:简单的终止一个或多个进程或是从一个多个死锁进程那里抢占资源。
进程终止有两种方法:
1. 终止所有死锁进程。
2. 一次终止一个死锁进程,直到死锁消失。
通过资源抢占要确定:
1.选择牺牲进程:应确定可抢占资源所在的进程,根据进程的重要程度来确定资源是否可被抢占。
2.回滚:被抢占资源的进程无法继续执行下去,因此需要回滚到之前的某个状态,以便死锁消除后,从这个状态继续执行。
3.饥饿:可抢占会带来饥饿问题。
啊。撒噶发几个款