【问题标题】:std::thread::join blocks indefinitely out of mainstd::thread::join 无限期地阻塞在 main 之外
【发布时间】:2016-03-03 13:54:01
【问题描述】:

std::thread::join 不会返回,即使线程例程已退出。

猜猜,我有课。

class A
{
public:
    A()
    {
        this->thr = std::thread(&A::foo, this);
    }
    ~A()
    {
        this->join();
    }
    void join()
    {
        this->cond.notify_all();
        if (this->thr.joinable())
        {
            this->thr.join();
        }
    }

private:
    void foo()
    {
        std::mutex mtx;
        std::unique_lock<std::mutex> lck(mtx);
        this->cond.wait(lck);
        MessageBox(L"I'm done!");
    }

private:
    std::thread thr;
    std::condition_variable cond;
};

我的应用程序包含A 的唯一实例。它是一个全局变量。 如果从析构函数调用A::joinstd::thread::join 将永远阻塞。 如果我手动调用A::join(例如在退出main 之前),一切都会好的。

我的main 看起来像这样:

A a;
int main()
{
    auto timeout = std::chrono::seconds(3);
    std::this_thread::sleep_for(timeout);

    // a.join();
}

顺便说一句,MessageBox 总是被执行的。

是不是和here一样的问题?

【问题讨论】:

  • that answer 没有回答您的问题吗?
  • @Barry,这似乎不是一个很好的解决方案。我工作,但如果main 不是那么微不足道怎么办?从我的应用程序中退出有很多不同的方式。因此,每次需要时我都必须手动 join 我的线程?
  • @MAKAKOKO 对不起,我对发生的事情感到困惑。我撤回了评论。
  • 顺便说一句,把notify_all()放在互斥锁下,你有竞争条件
  • 该示例在 vs2015 上运行良好(有和没有 a.join()MessageBox 调用已更正)并且notify_all() 没有竞争条件。

标签: c++ multithreading c++11


【解决方案1】:

是的,它与引用链接中的错误相同,因为您的示例也挂在_Thrd_join 上。您可能会对this question 感兴趣,其中包含更详细的分析。

【讨论】:

  • 就是这样!不幸的是,我不能投票。非常感谢。
  • @JohnSmith 作为认为 VS 是最好的 IDE 的人,运行时中的此类错误让我感到难过:(
【解决方案2】:

来自您的评论

“这似乎不是一个很好的解决方案。我工作,但如果主要怎么办 是不是很琐碎?有很多不同的方式可以退出我的 应用。因此,每次我都必须手动加入我的线程 需要吗?”

让 A 在你的 main 中成为 std::unique_ptr 怎么样。这样,无论你的 main 是如何退出的,它总是会在退出 main() 之前销毁 A 并且你不会遇到这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 2016-01-18
    相关资源
    最近更新 更多