我如何可以等待分離線程在C++來完成?等待分離的線程來完成在C++
我不關心的退出狀態,我只是想知道線程是否已經完成。
我試圖提供圍繞異步thirdarty工具同步封裝。問題是一個涉及回調的奇怪的競賽狀況崩潰。的進程是:
- 我所說的第三方,並註冊一個回調
- 當第三方完成,它使用回調通知我 - 在一個分離的線程我沒有真正的控制權。
- 我想從(1)要等到(2)被稱爲線程。
我想提供一個阻塞調用的機制來包裝這個。到目前爲止,我有:
class Wait {
public:
void callback() {
pthread_mutex_lock(&m_mutex);
m_done = true;
pthread_cond_broadcast(&m_cond);
pthread_mutex_unlock(&m_mutex);
}
void wait() {
pthread_mutex_lock(&m_mutex);
while (!m_done) {
pthread_cond_wait(&m_cond, &m_mutex);
}
pthread_mutex_unlock(&m_mutex);
}
private:
pthread_mutex_t m_mutex;
pthread_cond_t m_cond;
bool m_done;
};
// elsewhere...
Wait waiter;
thirdparty_utility(&waiter);
waiter.wait();
據我所知,這應該工作,它通常會,但有時它會崩潰。據我可以從核心文件確定,我猜測,這個問題是這樣的:
- 當回調廣播m_done結束,等待線程醒來
- 等待線程現在都是在這裏完成,等待被破壞。 Wait的所有成員都被銷燬,包括互斥和cond。
- 回調線程試圖從廣播點繼續,但現在使用的內存的被釋放,從而導致內存損壞。
- 當回調線程試圖返回時(高於我可憐的回調方法的級別),程序崩潰(通常使用SIGSEGV,但我曾多次看到SIGILL)。
我試了很多不同的機制來嘗試解決這個問題,但是他們都沒有解決這個問題。我仍然偶爾看到碰撞。
編輯:更多詳細信息:
這是一個大規模多線程應用程序的一部分,所以創建靜態等待是不切實際的。
我跑了一個測試,在堆上創建Wait,並故意泄漏內存(即Wait對象從不釋放),導致沒有崩潰。所以我相信這是一個等待被釋放太快的問題。
我也試過在wait
解鎖後用sleep(5)
進行測試,也沒有產生崩潰。儘管如此,我討厭依賴於這樣的混亂。
編輯:第三方細節:
我不認爲這是在第一個相關的,但我認爲它的越多,我認爲這是真正的問題:
的第三方的東西我提到過,爲什麼我無法控制線程:這是使用CORBA。
因此,CORBA有可能比我預期的更長時間地堅持對我的對象的引用。
不幸的是,這是一個大規模的多線程應用程序,我們真的想爲每個應用程序分別使用不同的Wait對象 - 否則它會讓我們太慢。 – Tim 2009-11-15 03:18:45
另外,如果我們使用一個靜態的Wait,那麼就有一個問題來試圖協調哪個線程需要恢復。 – Tim 2009-11-15 03:28:13
好的,你可以做到這一點。您可以將一個refcount字段添加到由全局互斥鎖保護的Wait對象。開始2的refcount,然後有回調和服務員都完成後遞減refcount。如果全局互斥變成瓶頸,還有其他更復雜的解決方案。 – 2009-11-15 03:29:25