如何檢測死鎖並快速定位死鎖位置

在遊戲中有時會遇到這樣一種狀況,某客戶端發了個請求到服務端,但收不到服務端回覆,看服務端的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官網..性能

相關文章
相關標籤/搜索