gpt4 book ai didi

c++ - 在 C++ 中等待分离的线程完成

转载 作者:可可西里 更新时间:2023-11-01 17:58:04 26 4
gpt4 key购买 nike

如何在 C++ 中等待分离线程完成?

我不关心退出状态,我只想知道线程是否已经结束。

我正在尝试围绕异步第三方工具提供一个同步包装器。问题是涉及回调的奇怪竞争条件崩溃。进度是:

  1. 我给第三方打电话,注册回调
  2. 当第三方完成时,它会使用回调通知我——在一个分离的线程中我无法真正控制。
  3. 我希望 (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();

据我所知,这应该有效,而且通常有效,但有时会崩溃。据我可以从核心文件确定,我对问题的猜测是这样的:

  1. 当回调广播m_done结束时,等待线程被唤醒
  2. 等待线程现在在这里完成,Wait 被销毁。 Wait 的所有成员都被销毁,包括 mutex 和 cond。
  3. 回调线程尝试从广播点继续,但现在正在使用已释放的内存,这会导致内存损坏。
  4. 当回调线程试图返回(高于我糟糕的回调方法的级别)时,程序崩溃(通常带有 SIGSEGV,但我见过几次 SIGILL)。

我尝试了很多不同的机制来尝试解决这个问题,但没有一个能解决问题。我仍然偶尔会看到崩溃。

编辑:更多细节:

这是大规模多线程应用程序的一部分,因此创建静态 Wait 不切实际。

我运行了一个测试,在堆上创建 Wait,并故意泄漏内存(即 Wait 对象永远不会被释放),并且没有导致崩溃。所以我确定这是 Wait 过早释放的问题。

wait 中解锁后,我还尝试使用 sleep(5) 进行测试,也没有产生崩溃。不过,我讨厌依赖这样的拼凑。

编辑:第三方详细信息:

一开始我不认为这是相关的,但我越想越觉得这是真正的问题:

我提到的第三方东西,以及为什么我无法控制线程:这是使用 CORBA。

因此,CORBA 持有对我的对象的引用的时间可能比预期的要长。

最佳答案

是的,我相信你所描述的正在发生(解除分配时的竞争条件)。解决此问题的一种快速方法是创建一个不会被销毁的 Wait 静态实例。只要您不需要同时有超过一名服务员,这就可行。

您还将永久使用该内存,它不会被释放。但看起来还不错。

主要问题是很难协调线程之间的线程通信构造的生命周期:您总是需要至少一个剩余的通信构造来在可以安全销毁时进行通信(至少在没有垃圾收集的语言中,例如 C++ ).

编辑:有关使用全局互斥锁进行重新计数的一些想法,请参阅评论。

关于c++ - 在 C++ 中等待分离的线程完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1736403/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com