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

在游戏中有时会遇到这样一种状况,某客户端发了个请求到服务端,但收不到服务端回复,看服务端的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;   

    1. TaskMutex mutex2;   

    1.   

    1. void m1() {   

    1.     try {   

    1.         mutex1.lock();   

    1.         sleep(1);   

    1.         mutex2.lock();   

    1.         mutex2.unlock();   

    1.         mutex1.unlock();   

    1.     } catch (...) {   

    1.         std::cout << boost::current_exception_diagnostic_information() << std::endl;   

    1.     }   

    1. }   

    1.   

    1. void m2() {   

    1.     try {   

    1.         mutex2.lock();   

    1.         sleep(1);   

    1.         mutex1.lock();   

    1.         mutex2.unlock();   

    1.         mutex1.unlock();   

    1.     } catch (...) {   

    1.         std::cout << boost::current_exception_diagnostic_information() << std::endl;   

    1.     }   

    1. }   

    1.   

    1. int main(int argc, char *argv[]) {   

    1.     try {   

    1.         IoScheduler scheduler(2);   

    1.         scheduler.schedule(boost::bind(&m1));   

    1.         scheduler.schedule(boost::bind(&m2));   

    1.         scheduler.stop();   

    1.     } catch (...) {   

    1.         std::cout << boost::current_exception_diagnostic_information() << std::endl;   

    1.     }   

    1.     std::cout << "will exit.." << std::endl;   

    1.     return 0;   

  1. }  


运行结果:app

 


    1. $./god_task_mutex_dead_lock   

    1. 2013-Aug-01 09:22:46.306073 FATAL god:task_mutex god/task_mutex.cpp:56 lock Deadlock found between 0x8148ca0 and 0x8148ce0   

    1. 2013-Aug-01 09:22:46.306710 FATAL : god/task_mutex.cpp:57 lock NOTREACHED   

    1. backtrace:   

    1. ./god_task_mutex_dead_lock() [0x80bfa78]   

    1. ./god_task_mutex_dead_lock() [0x8054d3b]   

    1. ./god_task_mutex_dead_lock() [0x80c733c]   

    1. ./god_task_mutex_dead_lock() [0x80cc7c3]   

    1. ./god_task_mutex_dead_lock() [0x80d839d]   

    1. terminate called without an active exception   

  1. 已放弃   


很方便,有木有。高并发

详情请访问libgod官网..性能

相关文章
相关标签/搜索