2009-11-02 35 views
9

我看到一個問題,在析構函數中調用boost的thread-> join會導致死鎖。我不明白爲什麼,而且我不太喜歡讓代碼在項目中正常工作(我不明白它爲什麼會這樣做)。在析構函數中加入boost :: thread實例

類聲明(我已經剝離的try/catch的run()方法爲簡潔:依據升壓線文檔,其結果應該是相同的有或沒有的話):

class B 
{ 
public: 
    void operator()(){run();} 
    void run(); 
    void shutdown(); 
    ~B(); 
    B(); 
    boost::thread *thr; 
    bool shutdown_requested; 
}; 

void B::shutdown() 
{ 
    shutdown_requested = true; 

    if (thr != NULL) 
    { 
     thr->interrupt(); 
     thr->join(); // deadlock occurs here! 
     delete thr; 
     thr = NULL; 
    } 
} 

B::~B() 
{ 
    shutdown(); 
} 

B::B() 
{ 
    thr = new boost::thread(boost::ref(*this)); 
} 

void B::run() 
{ 
    while (!shutdown_requested) 
    { 
     boost::xtime xt; 
     boost::xtime_get(&xt, boost::TIME_UTC); 
     xt.sec += 30; 
     boost::this_thread::sleep(xt); 
    } 
} 

片段不工作:

int main() 
{ 
    B *b = new B; 

    Sleep(5000); 
    printf("deleting \n");fflush(stdout); 
// b->shutdown(); 
    delete b; 
    printf("done\n");fflush(stdout); 

    return 0; 
} 

摘錄其中的工作原理:

int main() 
{ 
    B *b = new B; 

    Sleep(5000); 
    printf("deleting \n");fflush(stdout); 
    b->shutdown(); 
    delete b; 
    printf("done\n");fflush(stdout); 

    return 0; 
} 

我覺得原因行爲有事情做在這個片段升壓文檔:

Boost.Thread的用戶必須確保 的引用的目標會超越 執行新創建的線程。

但我真的不明白爲什麼死鎖 - 連接線程不會調用B上的析構函數,並且在run()方法應該退出時不會刪除對象本身。

+1

好問題,並且問得很好。我不知道答案,但是你看過boost :: thread的實現嗎?還是你嘗試調試它?也許這給你一個提示。從查看示例代碼,我會說它應該工作正常。 – MP24 2009-11-02 13:16:12

+0

謝謝,我通過加入調試器發現了問題。它與泄漏檢測代碼有關。 – laura 2009-11-02 13:47:45

回答

4

我發現這個問題:它歸結爲一個過分熱心的程序員。

我最初使用DUMA編譯我的項目(http://sourceforge.net/projects/duma/),以查看我的當前模塊的實現是否無泄漏。不幸的是,我的測試沙箱也有杜馬設置,直到我在調試器中逐步完成代碼之前,我並沒有意識到這一點。

刪除所有內存泄漏檢測後,一切都按預期工作。

+0

請注意,您可以接受您自己的答案,將您的問題標記爲已回答。 – MP24 2009-11-02 14:33:22

+0

不幸的是兩天後。再次感謝您的幫助 – laura 2009-11-02 14:45:28

相關問題