一处死锁分析

最近在进行回归测试的时候,QA同学反映有一处死锁,导致大量线程Hang死。通过pstack查看后,发现如下可疑的两个线程:

看到此处就觉得比较奇怪,Thread2被Hang住很正常,因为A的读锁被Thread1占有了,此时无法加上A的写锁,但是为什么Thread 1会被锁死呢?因为此时B的读锁最少被Thread 2加上了,说明没有写线程占有写锁。且其他大量线程都被锁死在请求B的读锁的时候。

排除掉所有那些请求B的读锁被Hang死的线程后,发现了一个可疑的线程,这个线程Hang在如下位置

即存在一个线程在请求B的写锁,且处于等待的过程中。疑点比较明显,于是gdb之后,打印了一下这个pthread_rwlock_t的属性,发现其__rw_kind的属性值是1,顺藤摸瓜,发现这个读写锁在初始化的时候使用了如下过程:

其中PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP表明写锁优先的模式,即有写者等待时,所有读者被阻塞,所以因为Thread 3在获取B的写锁,则Thread 1无法获取B的读锁,从而导致A的读锁不会被释放,此种情况Thread 2无法获取A的写锁,也不会释放B的读锁,导致死锁。

解完Bug后,大呼原来多线程情况下,两个以前线程也有可能在某些情况下造成死锁。即只要有加锁顺序不一致的情况,且有读写锁混合的情况下,如果有写锁优先的情况,也有可能导致死锁。

2013年5月14日 | 归档于 C++, Linux, 工作, 技术
  1. bbiao
    2013年7月6日 10:46 | #1

    换了Disqus,试一下。

发表评论

取消
XHTML: 您可以使用这些标签: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">