Error

C++博客 首页 新随笔 联系 聚合 管理
  217 Posts :: 61 Stories :: 32 Comments :: 0 Trackbacks
 

网上很容易找到一个用boost::shared_mutex来作为读写锁的例子:

  1. typedef boost::shared_mutex rwmutex;  
  2. typedef boost::shared_lock<rwmutex> readLock;  
  3. typedef boost::unique_lock<rwmutex> writeLock;   

 

一直没有怀疑过这个做法,直到最近项目中出现一个死锁问题,查了很久才发现是上面这种写法造成的。

写测试代码还原死锁的情景如下:

  1. #include <boost/thread/shared_mutex.hpp>   
  2. #include <boost/thread/shared_lock_guard.hpp>   
  3. #include <boost/thread.hpp>   
  4. #include <iostream>   
  5. #include <Windows.h>   
  6. using namespace std;  
  7. typedef boost::shared_mutex rwmutex;  
  8. typedef boost::shared_lock<rwmutex> readLock;  
  9. typedef boost::unique_lock<rwmutex> writeLock;  
  10.   
  11. rwmutex m_mutex;  
  12. void func1()  
  13. {  
  14.     writeLock lock1(m_mutex);  
  15.     cout << "fffffffffffffff" << endl;  
  16. }  
  17.   
  18. int main()  
  19. {  
  20.     {  
  21.         boost::thread tt(func1);  
  22.         readLock lock(m_mutex); // 加读锁   
  23.         {  
  24.             Sleep(3000);  // 故意睡眠3秒将线程切换出去   
  25.             readLock lock(m_mutex); // 醒来后再次加读锁   
  26.             cout << "rrrrrrrrrrrrrrrrrr" << endl;  
  27.         }  
  28.     }  
  29. }  

情形描述如下:

1:主线程先给m_mutex加读锁。

2:主线程故意睡眠3秒将执行权限切换出去。

3:func1线程获得执行机会,尝试加写锁被挂起。因为主线程已经有一个读锁占用,写锁必须等待这个读锁释放才能进入。

4:主线程睡眠3秒醒来,后续代码想获取一个读锁。由于这个时候已经有一个写锁在等待进入,那么这个读锁排队在写锁后面,同样被挂起。

5:主线程和func1线程都被挂起了,发生死锁。

上面的测试代码,如果中间没有sleep(3000),出现死锁的概率很低,但总归是存在死锁的可能。

 

总结:

以前一直认为readLock锁和递归锁一样,在同一个线程多次进入没有关系才会造成上面的死锁出现。所以,boost::shared_lock使用要小心,千万不要同一个线程多次进入。

posted on 2013-01-31 18:46 Enic 阅读(1548) 评论(0)  编辑 收藏 引用 所属分类: about boost

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理