目录
1.死锁产生的场景(两种)
- 第一种场景:线程加锁之后,并没有释放互斥锁
-
- 第二种场景:两种线程分别拿着一把锁,还想请求对方的锁。
-
- 模拟:
-
- 查看调用堆栈
-
-
2.死锁的gdb分析
- 命令thread apply all bt :展示所有线程的调用堆栈
- 扫描二维码关注公众号,回复: 14445626 查看本文章
-
- 命令 t + 线程序号 :跳转到某一个线程当中
-
- 互斥锁变量中的_owner表示当前互斥锁被哪个线程所持有
-
- gdb+正在运行的程序(死锁分析)
- 命令:gdb + attach+线程id
- 这中调式方式和gdb+可执行的程序的调式方式的区别在于,不用打断点,可以直接调式,分析死锁产生的原因。
3.死锁的必要条件
- 1不可剥夺:线程获取到互斥锁之后,除了自己释放,其他线程不能进行释放
- 2.循环等待:线程A拿着1锁,请求2锁,同时线程B拿着2锁,请求1锁
- 3.互斥条件:一个互斥锁,在同一时间只能被一个线程所拥有
- 4.请求与保持:吃着碗里的,看着锅里的
4.代码怎么预防死锁
- 破坏必要条件:循环等待和请求与保持
-
- 加锁顺序一致,都先加1锁,再加2锁
-
- 避免锁没有被释放:在所有可能线程退出的地方都进行解锁
- 资源一次性分配:多个资源在代码当中有可能每一个资源都需要使用不同的锁进行保护
- 例如:
- 全局变量A,需要1锁保护,全局变量B,需要2锁保护
- 线程需要同时拿到两个全局变量才能运行,就有可能多个线程在使用这两个资源的时候,出现循环等待的情况
- 解决方案:两个全局变量用一把锁保护(资源一次性分配)。
- 例如: