关于临界资源访问互斥量的死锁问题

死锁简单解释:

就是(进程/线程)对象1,占据资源A,同时申请资源B,而(进程/线程)对象2,占据资源B,同时申请资源A,

如果双方均阻塞等待,且不释放已占用资源,这就发生了死锁。

死锁的发生:

如果程序比较简单,结构清晰,正常情况下死锁是完全能够很清晰的做到人为避免的。但是事实却是死锁会在不经意间

就发生了,我们永远记住一个道理:程序结构与思路做到简单清晰是第一战略,永远不要试图用你所谓的聪明才智去挑战复

杂的程序逻辑,否则迟早会跌一个你爬都爬不起来的跟头。

如何解决呢:

1) 把逻辑做到最简捷,一目了然最好,即使有问题,解决起来也是分分钟的事情,因为事先的设计上你已经下足了功夫。

2) 稍微复杂一点的,可以通过仔细的控制加锁的顺序来避免思索的发生。比如有三个临界锁ABC,  在所有使用的地方

   严格按照统一顺序加锁、解锁。注意顺序使用当中后继锁对象可以省略,前驱一定不能省。

   比如((进程/线程)对象1) 使用 A-B-C 顺序申请锁,那么其他(进程/线程)对象,可使用顺组组合: A;A-B ;A-B-C

3) 有时候对互斥量的锁排序是困难的,不容易做成简单的层次,(在自己力所能及的情况下,总应该设计出强制的层级顺序),

    就需要另外一种方法:即使通过破解死锁条件的几个条件来入手:

    a.释放自己也已占用的资源,过一段时间再重试,

    b.使用“尝试”加锁接口,避免长时间阻塞。

4)增大锁的粒度,减少锁的个数,来化简程序逻辑结构,这有可能会降低程序的并发性能(也要参考锁本身的系统开销,

    锁的粒度也是要讲究一个平衡),当然在满足锁需求的情况下,在代码复杂度和性能之间找到一个平衡。

5)其他一些更高级的技术:无锁算法,乒乓缓存,等等,更重要的是结合实际的业务逻辑找到一个合适的点。

总结

程序设计本身就是平衡的艺术,时间与空间的平衡,性能与代价的平衡、 成本与收益的平衡,设计与需求的平衡。

原文地址:https://www.cnblogs.com/Esperanto/p/5731912.html