std::thread::join 无限期地阻塞在 main 之外

Posted

技术标签:

【中文标题】std::thread::join 无限期地阻塞在 main 之外【英文标题】:std::thread::join blocks indefinitely out of 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() 没有竞争条件。 【参考方案1】:

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

【讨论】:

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

来自您的评论

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

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

【讨论】:

以上是关于std::thread::join 无限期地阻塞在 main 之外的主要内容,如果未能解决你的问题,请参考以下文章

std::thread.join() 死锁

OpenCV 分配导致 std::thread::join 中的段错误

从命名管道读取不会给出任何输出并无限期地阻塞代码

使用 SVF2 时,await AggregateView.waitForLoadDone() 有时会无限期阻塞

SQL Server 的锁定和阻塞

尝试读取资源时 ReaderWriterLock 阻塞