我如何可以等待分离线程在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