死锁的产生和避免
死锁的定义
该组进程(线程)的每一个进程(线程)都在等待仅由该组进程(线程)的其他进程(线程),才能引发的事件,该进程(线程)是死锁的
引入锁是为了解决多线程直接的同步与互斥问题
典型的两种死锁情况
1 线程自己将自己锁住
同一个线程先后两次调用lock,第二次调用时由于锁已经被占用,该线程会挂起等待,然而锁是被自己占用,该线程被挂起没有机会释放,因此永远处于等待状态形成死锁
2多线程抢占资源被困
线程A获得锁1,线程B获得锁2,
线程A调用lock试图获得锁2,结果需要挂起等待线程B释放锁2,
同时线程B调用lock试图获得锁1,结果需要挂起等待线程A释放锁1
于是乎线程A,B永远处于挂起状态
引起死锁的原因
1、竞争不可抢占资源
例如共享文件时引起死锁
系统中有两个进程P1和P2,他们都准备写两个文件,这两者都属于可重用,不可抢占性资源
当P1打开F1同时P2打开F2,当P1想打开F2的时候,F2已经被占用引起P1阻塞
2、竞争可消耗资源
例如进程间通信引起死锁
系统中三个进程P1,P2,P3 其中m1,m2,m3是可消耗资源,进程1产生m1,接收进程3发来的m3, 进程2产生m2,接收来自进程P1发来的m1, 进程P3产生m3,接收来自进程P2发来的m2
如果每个进程都先发送消息,则可用顺利运行,但如果每个进程都先接收别人的消息而不产生消息,则会永远等待下去
* 3、进程推进顺序不当*
产生死锁的必要条件?
1、互斥条件
进程(线程)所申请的资源在一段时间内只能被一个进程(线程)锁占用。
2、请求和保持条件
该进程(线程)已经占有至少一个资源,但又提出新的资源请求, 而该资源被其他进程(线程)占用
3、不可抢占条件
进程(线程)已经获得的资源在未使用完之前不能被抢占
4、循环等待条件
发送死锁时必然存在一个进程(线程)资源的循环链
死锁的处理方法
1、预防死锁 :破坏死锁产生的必要条件中的一个或多个(互斥条件不可破坏)
2、避免死锁 : 在资源分配过程中,防止系统进入不安全区域
3、检测死锁 :检测出死锁的发送,采取措施解出死锁
4、解出死锁 :检测出死锁后,采取措施解出死锁
利用银行家算法避免死锁
每一个线程进入系统,声明运行时所需要类型资源的最大数(不超过系统拥有的总量),
线程请求一组资源时,系统必须确定是否有足够的资源给该进程,
如果有则进一步计算资源分配给进程后,是否会让系统处于不安全的状态
如果分配资源的时候能找安全的序列则将资源分配给它,否则等待。