【线程】--------认识死锁

一、死锁

1)提出
多线程与多进程提高了系统资源的利用率,然而并发执行也会带来一些问题,如死锁。
2)概念
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
3)死锁在现实生活中的实例
在一个计算机系统中,只有一个打印机和一个输入设备。进程一正在占用输入设备,同时又提出使用打印机的请求,而进程二正在占用打印机,同时提出使用输入设备,就这样,两个进程只能无休止的进行等待,两个进程就会陷入死锁状态

二、产生死锁的必要条件

产生思索的根本原因:
竞争资源和进程推进顺序非法
产生死锁必须同时满足以下四个条件
1)互斥条件
指进程对所分配的资源进行排他性使用,即在某一时刻,某一资源只能由一个进程占用,如果其他进程请求资源,则让其他进程进行等待,直到占用进程释放。
2)请求和保持条件
指进程已经占有至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
3)不剥夺条件
指进程占有某个资源后,在没有自己主动释放时,该资源不能被剥夺。
4)环路等待条件
指在发生死锁时,必然存在一个进程——资源的环形链,一个等待另一个被占用的资源。
这里写图片描述

三、解决死锁

特殊的处理方法:鸵鸟策略
就像鸵鸟一样,遇到危险就将头埋在地底下,假装看不到,将危险忽略。虽然不算是一个算法,但在实际系统中是广泛使用的,所以在计算机操作系统中,死锁发生且影响系统正常运行时,手动干预—重新启动。
1.预防死锁
通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或几个。此方法较易实现,已被广泛使用,但会降低系统资源利用率。
预防死锁,预先破坏产生死锁的四个条件。互斥不可能破坏,所以有如下三种方法:
1)、破坏请求和保持条件,
进程必须等所有要请求的资源都空闲时才能申请资源,这种方法会使资源浪费严重(有些资源可能仅在运行初期或结束时才使用,甚至根本不使用)。
允许进程获取初期所需资源后,便开始运行,运行过程中再逐步释放自己占有的资源,比如有一个进程的任务是把数据复制到磁盘中再打印,前期只需获得磁盘资源而不需要获得打印机资源,待复制完毕后再释放掉磁盘资源。这种方法比第一种方法好,会使资源利用率上升。
2)、破坏不可抢占条件
这种方法代价大,实现复杂。
3)、破坏循坏等待条件
对各进程请求资源的顺序做一个规定,避免相互等待。这种方法对资源的利用率比前两种都高,但是前期要为设备指定序号,新设备加入会有一个问题,其次对用户编程也有限制。
2.避免死锁
在资源的动态分配过程中,使用某种方法去防止系统进入不安全状态。
死锁避免的两种方法:

  • *如果一个进程的请求会导致死锁,则不启动此进程。
  • *如果一个进程的增加的资源请求会导致死锁,则不允许此分配。

死锁避免的优点是它不需要死锁预防中的抢占和回滚进程,并且比死锁预防的限制少。但是,它在使用中也有很多限制:

  • *必须事先声明每个进程请求的最大资源。

  • *考虑的进程必须是无关的,也就是说,它们执行的顺序必须没有任何同步要求的限制

  • *分配的资源数目必须是固定的。

  • *在占有资源时,进程不能退出。

3.死锁检测并解除
死锁预防策略是非常保守的,它们通过限制访问资源和在进程上强加约束来解决死锁问题。
死锁检测策略则完全相反,它不限制资源访问或约束进程行为。
对于死锁检测来说,只要有可能,被请求的资源就被授权给进程。操作系统周期性的执行一个算法来检测前面的循环等待条件。
通过系统所设置的检测机构,可以及时发现与死锁有关的进程和资源,然后将进程从死锁状态中解脱出来,常用的措施是撤销或挂起一些进程(剥夺),以便回收某些资源,再将这些资源分配给已处于阻塞状态的进程,使之变为就绪态,使之继续运行,此方法实施难度比较大。

四、常见避免死锁的算法

1.利用银行家算法避免死锁
Dijkstra的银行家算法是最有代表性的避免死锁的算法。
2.银行家算法中的数据结构

1)可利用资源向量Available
是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j]=K,则表示系统中现有Rj类资源K个。
2)最大需求矩阵Max
这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。
3)分配矩阵Allocation
这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的 数目为K。
4)需求矩阵Need。
这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。

3、银行家算法

在避免死锁的方法中,所施加的限制条件较弱,有可能获得令人满意的系统性能。在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状态,便可以避免发生死锁。
银行家算法的基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。它是最具有代表性的避免死锁的算法。
设进程cusneed提出请求REQUEST [i],则银行家算法按如下规则进行判断。
(1)如果REQUEST [cusneed] [i]<= NEED[cusneed][i],则转(2);否则,出错。
(2)如果REQUEST [cusneed] [i]<= AVAILABLE[i],则转(3);否则,等待。
(3)系统试探分配资源,修改相关数据:
AVAILABLE[i]-=REQUEST[cusneed][i];
ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];
NEED[cusneed][i]-=REQUEST[cusneed][i];
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。

猜你喜欢

转载自blog.csdn.net/daboluo521/article/details/80145128
今日推荐