本文主要描述解决多线程死锁的避免协议。
死锁主要是多线程资源分配时,产生了圆圈等待。
箭头指向T ,表示被T拥有;箭头指向R,表示请求拥有。很明显,上图的资源分配导致死锁。
一般来说,发现这种可能时,需要做适当的资源分配来打破圆圈。
很明显,调整了资源分配,打破了该时刻的死锁。
如果圆圈等待是设计本身所必须的,那就是用死锁避免协议吧。优先权天花板控制协议是可以做到一定不发生死锁的协议。
协议基础:
1. 给线程(任务)分配优先权,高优先权的线程可以抢占低优先权的cpu 时间。
2. 系统资源也有优先权,它是可能占用该资源的线程优先权中最高者,称为"优先权天花板".
3. 在任意时刻,一个系统的当前使用资源当中,最高的优先权天花板,称为"当前优先权天花板".
4. 权限继承,一个T获得另外一个的优先权。
当一个T 请求一个R时,协议的规则如下:
1. 如果R被占用,则T阻塞。
2. 如果R空闲,且T的优先权比当前优先权天花板的高,则R 分配给T .
3. 如果当前优先权天花板属于T当前保持的资源之一,则R分配给T;反之,T阻塞.
4. 如果T阻塞了优先权更高的任务,则T继承其优先权,并且按照此优先权执行,直到T释放了每个优先权天花板高于或等于T的优先权资源,然后,任务回到原来的优先权。
下面,看一下优先权天花板是如何避免死锁的。
通常的死锁:
1. T1占用R1.
2. T2占用R2.
3. T1请求R2,R2被占用,T1阻塞.
4. T2请求R1,R1被占用,T2阻塞。
5. 阻塞.
优先权天花板实例:
1. T1 优先权10.
2. T2 优先权5.
3. R1,R2由于均可能被T1占用,优先权天花板均为10(L).
情景1,T1先占用:
1. T1占用R1,T1=10,R1 = 10,L = 10.
2. T2请求R2,由于规则三,L > T2, T2阻塞.
3. T1 请求R1,由于规则三,L = T1,T1占用R2.
4. T1使用完R1,R2,T2开始占用资源。
情景2,T2先占用:
1. T2占用R1,T2 = 5,R1 = 10, L = 10.
2. T1请求R2,由于规则三,L = T1, 但L不是T1当前拥有的资源,T1阻塞.
3. T2请求R2,由于规则三,L是T2当前拥有的资源,T2占用R2.
4. T2使用完R1,R2,T1开始占用资源.