如何检测死锁并快速定位死锁位置

在游戏中有时会遇到这样一种情况,某客户端发了个请求到服务端,但收不到服务端回复,看服务端的log,也没任何错误,最后调试跟踪代码,发现代码死锁了。遇到这种情况比较纠结,于是捣腾了一个自动检测死锁的功能,如果发生死锁,会马上打印堆栈信息,并终止程序,如果是在调试环境中,会自动断点到发生死锁的地方。
实现思路如下:
比如Task A已经拥有了Lock 1,并准备去获取Lock 2,此时检测一下Lock 2是否被其它Task拥有了,如果没有,那Task A就很Happy的直接获取Lock 2就行了。如果Lock 2已经被Task B拥有了,那就检测一下Task B是否在等待Lock 1,如果是的话就说明是死锁了,此时打印一下堆栈信息,如果在调试环境,就中断调试,以方便查看死锁现场,否则直接退出程序。
这样虽然上锁的效率会降低,但很快就能发现死锁。一般发布游戏到线上的时候,就把死锁检测功能去掉,也不会影响性能。
看下我的测试代码:



  1. TaskMutex mutex1;   
  2. TaskMutex mutex2;   
  3.   
  4. void m1() {   
  5.     try {   
  6.         mutex1.lock();   
  7.         sleep(1);   
  8.         mutex2.lock();   
  9.         mutex2.unlock();   
  10.         mutex1.unlock();   
  11.     } catch (...) {   
  12.         std::cout << boost::current_exception_diagnostic_information() << std::endl;   
  13.     }   
  14. }   
  15.   
  16. void m2() {   
  17.     try {   
  18.         mutex2.lock();   
  19.         sleep(1);   
  20.         mutex1.lock();   
  21.         mutex2.unlock();   
  22.         mutex1.unlock();   
  23.     } catch (...) {   
  24.         std::cout << boost::current_exception_diagnostic_information() << std::endl;   
  25.     }   
  26. }   
  27.   
  28. int main(int argc, char *argv[]) {   
  29.     try {   
  30.         IoScheduler scheduler(2);   
  31.         scheduler.schedule(boost::bind(&m1));   
  32.         scheduler.schedule(boost::bind(&m2));   
  33.         scheduler.stop();   
  34.     } catch (...) {   
  35.         std::cout << boost::current_exception_diagnostic_information() << std::endl;   
  36.     }   
  37.     std::cout << "will exit.." << std::endl;   
  38.     return 0;   
  39. }  

运行结果:


  1. $./god_task_mutex_dead_lock   
  2. 2013-Aug-01 09:22:46.306073 FATAL god:task_mutex god/task_mutex.cpp:56 lock Deadlock found between 0x8148ca0 and 0x8148ce0   
  3. 2013-Aug-01 09:22:46.306710 FATAL : god/task_mutex.cpp:57 lock NOTREACHED   
  4. backtrace:   
  5. ./god_task_mutex_dead_lock() [0x80bfa78]   
  6. ./god_task_mutex_dead_lock() [0x8054d3b]   
  7. ./god_task_mutex_dead_lock() [0x80c733c]   
  8. ./god_task_mutex_dead_lock() [0x80cc7c3]   
  9. ./god_task_mutex_dead_lock() [0x80d839d]   
  10. terminate called without an active exception   
  11. 已放弃   

很方便,有木有。

详情请访问libgod官网..

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值