死锁是什么?如何预防和避免死锁?
官方解析
死锁是指两个或多个进程在执行过程中因争夺资源而造成的一种僵局,当进程处于死锁状态时,它们将无法继续执行,而只能相互等待,直到被外部的程序干预或自行放弃。
预防和避免死锁需要采取一些措施,包括:
-
避免资源独占:尽量避免一个进程在获得了某些资源后再次请求其他资源,而应该将所有需要的资源一次性申请到位。
-
避免资源持有和等待:当一个进程占用了一些资源并等待另一些资源时,其他进程就无法使用这些资源,容易引发死锁。因此,尽可能减少资源持有和等待时间。
-
避免资源互斥:有些资源在同一时间只能被一个进程占用,比如打印机、磁带机等,需要采用一些技术手段来避免资源互斥的问题。
-
引入资源剥夺策略:当一个进程请求的资源被其他进程占用时,可以采取剥夺资源的策略,即暂停占用该资源的进程,直到该资源被释放后再恢复该进程的执行。
-
引入进程抢占策略:当一个进程等待时间过长时,可以采取抢占其资源的策略,即中断正在执行的进程,强制释放其占用的资源。
以上是预防和避免死锁的一些方法,具体选择哪种方法需要根据具体情况进行分析和判断。
死锁是什么?
多线程编程中,当两个线程为了保护两个不同的共享资源而使用了两个互斥锁,如果应用不当,会造成两个线程都在等待对方释放锁,没有外力的作用下,这些线程会一直互相等待,就没办法继续运行,这就是发生了死锁
产生死锁的四个必要条件
-
互斥条件:多个线程不能同时使用一个资源
-
持有并等待条件:线程A在等待资源2的同时并不会释放自己已经持有的资源1
-
不可剥夺条件:在自己使用之前不能被其他线程获取
-
环路等待条件:两个线程获取资源的顺序构成了环形链
如何预防和避免死锁?
只要破坏其中一个必要条件就可以避免死锁,最常见的并且可行的就是使用资源有序分配法,来破坏环路等待条件
例子1:线程之间如何避免死锁
-
线程A和线程B获取资源的顺序要一样
-
线程 A 是先尝试获取资源 A,然后尝试获取资源 B 的时候
-
线程 B 同样也是先尝试获取资源 A,然后尝试获取资源 B
-
线程 A 和 线程 B 总是以相同的顺序申请自己想要的资源
例子2:MySQL 如何避免死锁
-
设置事务等待锁的超时时间
-
开启主动死锁检测
其他:利用工具排查死锁问题
-
java:jstack
-
C:pstack + gdb