概述
在我们的Linux程序中,我们经常会碰到死锁程序,这个时候,千万不要凭借自己的满腔热水去分析,我自己本人曾经花费长达一周的时间,天天加班去梳理整个锁的层级关系,下面要给大家介绍的是最直接有效的锁分析方法。
Linux下程序死锁检测方法
- 锁场景分析
- 1. 互斥锁
- 2. Lock 2次
- 结合实际例子分析死锁
锁场景分析
1. 互斥锁
运用场景,假设有2个线程
线程1
{
锁A
//
// do something
锁B
}
线程2
{
锁B
//
// do something
锁A
}
这种情况下,就是互斥锁.
获取锁:
线程1获取了锁A,等锁B
线程2获取了锁B,等锁A。
问题产生:
线程1,在等锁B时候,锁B已经为线程2锁所获得.
线程2,在等锁A的时候,锁A已经为线程1所获得.
线程1和线程2发生互斥,产生死锁情况.
2. Lock 2次
锁住2次的问题也很频繁,但是这个问题是最容易梳理的,只需要大家平时注意编写代码的习惯即可,下面的例子依然也可以很容易定位出锁2次的问题.
结合实际例子分析死锁
- 我的媒体服务器产生了死锁.
定位出发生死锁的进程,并打印出此进程的所有线程信息:
gdb attach 4911
info thread
输出如下:
注意上图中红框2边的数字,左边是线程ID,右边是的Lwp我也不知道是哈,但是很有用.
首先我们来看下,线程25是在哪里发生了死锁,并且我们需要知道,如果锁住了,那么是哪个线程获得了锁.
thread 25 //进入到线程25
where // 打印出锁的位置信息
f 3 // 进入到断点3号,可以很明确的知道,是此处发生了死锁.
print send_queue_mutex // 打印出锁的信息,用于辅助分析
这里的输出信息很重要,上面的信息已经阐述了2个重要的信息:
lock=2 ,目前被锁2次,说明我自己是要第三次锁 。(基本可以判定是锁2次在别的线程发生了)
owner = 2236,锁2次的线程在2236.
结合上图,我们来看看2236到底在哪个线程中:
这里很明显了,2236是线程27.
重复上述操作,定位出线程27发生死锁的原因:
结合我自己的代码,最终死锁原因如下:
这里,我们发现了:
unlock() 应该在if(msgSendCount > 0) 后面释放:
改正后如下
最后
以上就是苹果小鸽子为你收集整理的Linux下程序死锁检测方法的全部内容,希望文章能够帮你解决Linux下程序死锁检测方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复