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


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

    看下我的测试代码:

    TaskMutex mutex1;   
    
    TaskMutex mutex2;   
    
    
    
    void m1() {   
    
        try {   
    
            mutex1.lock();   
    
            sleep(1);   
    
            mutex2.lock();   
    
            mutex2.unlock();   
    
            mutex1.unlock();   
    
        } catch (...) {   
    
            std::cout << boost::current_exception_diagnostic_information() << std::endl;   
    
        }   
    
    }   
    
    
    
    void m2() {   
    
        try {   
    
            mutex2.lock();   
    
            sleep(1);   
    
            mutex1.lock();   
    
            mutex2.unlock();   
    
            mutex1.unlock();   
    
        } catch (...) {   
    
            std::cout << boost::current_exception_diagnostic_information() << std::endl;   
    
        }   
    
    }   
    
    
    
    int main(int argc, char *argv[]) {   
    
        try {   
    
            IoScheduler scheduler(2);   
    
            scheduler.schedule(boost::bind(&m1));   
    
            scheduler.schedule(boost::bind(&m2));   
    
            scheduler.stop();   
    
        } catch (...) {   
    
            std::cout << boost::current_exception_diagnostic_information() << std::endl;   
    
        }   
    
        std::cout << "will exit.." << std::endl;   
    
        return 0;   
    
    }  
    

    运行结果:

    $./god_task_mutex_dead_lock   
    
    2013-Aug-01 09:22:46.306073 FATAL god:task_mutex god/task_mutex.cpp:56 lock Deadlock found between 0x8148ca0 and 0x8148ce0   
    
    2013-Aug-01 09:22:46.306710 FATAL : god/task_mutex.cpp:57 lock NOTREACHED   
    
    backtrace:   
    
    ./god_task_mutex_dead_lock() [0x80bfa78]   
    
    ./god_task_mutex_dead_lock() [0x8054d3b]   
    
    ./god_task_mutex_dead_lock() [0x80c733c]   
    
    ./god_task_mutex_dead_lock() [0x80cc7c3]   
    
    ./god_task_mutex_dead_lock() [0x80d839d]   
    
    terminate called without an active exception   
    

    很方便,有木有。

  • 相关阅读:
    Asp.Net MVC4入门指南(3):添加一个视图
    Asp.Net MVC4入门指南(2):添加一个控制器
    Asp.Net MVC4入门指南(1): 入门介绍
    .net平台借助第三方推送服务在推送Android,IOS消息(极光推送_V2版本)
    ASP.NET网站实现中英文转换(本地化资源)
    .net 内置对象之Session对象和Session的过期时间
    SQL 单表分页存储过程和单表多字段排序和任意字段分页存储过程
    Js键盘事件全面控制,回车按键事件,键盘对应按键码,按键事件兼容各个浏览器。
    C# WebBrowser控件详解
    html .net 网页,网站标题添图标
  • 原文地址:https://www.cnblogs.com/qianggezhishen/p/7349320.html
Copyright © 2020-2023  润新知