目录
1.死锁问题
1.1、死锁的两种场景
-
第一种场景
- 线程加锁之后并没有将锁释放
- 1.这里我们模拟两个线程导致死锁的情况:将锁锁上之后线程退出,导致其他线程拿不到这把锁造成死锁情况
- 我们让程序跑起来发现一直不退出
- 然后查看调用堆栈我们发现一个创建出来两个线程现在只剩下一个,而且他在死等锁,
- 2.接下来我们来模拟一个线程将锁锁上没有释放,导致死锁的情况:
- 我们运行程序发现程序卡死
- 我们查看调用栈发现是和上面一样的情况
-
第二种场景
- 两个线程都持有对方想要的锁,然后造成死锁
- 代码模拟:我们来模拟两个进程互相持有对方想要的锁的情况
- 运行结果发现直接卡死
- 我们查看调用栈发现两个进程都在等待锁造成死锁
- 这时无论两个线程的最后一行下面写什么代码都是无法执行的
- 死锁gdb调试
- t+线程序号=跳转到某个线程当中
- 【p g_lock】中owner可以看到锁的持有者
- 两个线程都持有对方想要的锁,然后造成死锁
2.造成死锁的必要条件
-
2.1、不可剥夺
- 不可剥夺:线程获取到互斥锁之后, 除了自己释放,其他线程是不能进行释放的。
-
2.2、循环等待
- 循环等待:线程A拿着1锁, 请求2锁, 同时线程B拿着2锁, 请求1锁。
- 循环等待:线程A拿着1锁, 请求2锁, 同时线程B拿着2锁, 请求1锁。
-
2.3、互斥条件
- 互斥条件: 一个互斥锁,在同一时间只 能被一个线程所拥有。
-
2.4、请求与保持
- 请求与保持:吃着碗里的, 看着锅里的。(已经拿到一个锁,还想请求另外一个锁,和上面的循环等待场景相似)
3.预防死锁
-
3.1、破坏必要条件:循环等得请求与保持
- 运行结果:程序没有卡死正常退出。
- 加锁顺序一致,都先加1锁, 再加2锁
- 运行结果:程序没有卡死正常退出。
-
3.2、避免锁没有被释放
- 在所有可能线程退出的地方都进行解锁
-
3.3、资源一次性分配
- 多个资源在代码当中又可能每一个资源都需要使用不同的锁进行保护
- 例如:
- 全局变量A,需要1锁
- 全局变量B,需 要2锁
-
就有可能多个线程在使用这两个资源的时候,出现循环等待的情况。 - 这里的解决方式我们只需要给将A和B用同一把锁保护即可(资源一次性分配)。
看到这里如果觉得有用不如点个赞再走吧!!!