简体   繁体   English

std :: thread :: join无限期地阻塞了main

[英]std::thread::join blocks indefinitely out of main

std::thread::join does not return, even if the thread routine is exited. 即使退出线程例程, std::thread::join也不会返回。

Guess, I have a class. 猜猜,我上课了。

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;
};

My application contains the only instance of A . 我的应用程序包含唯一的A实例。 It is a global variable. 这是一个全球变量。 If A::join is called from the destructor, std::thread::join blocks forever. 如果从析构函数调用A::join ,则std::thread::join永久阻塞。 If I call A::join manually (eg before exiting main ), everything is alright. 如果我手动调用A::join (例如在退出main之前),一切都没问题。

My main looks like this: 我的main看起来像这样:

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

    // a.join();
}

By the way, MessageBox is always executed. 顺便说一下,MessageBox总是被执行。

Is that the same problem as here ? 是同样的问题, 在这里

Yes it is the same bug as in the referenced link since your example also hangs on _Thrd_join . 是的,它与引用的链接中的错误相同,因为您的示例也挂起在_Thrd_join You could be interrested in this question which contains a far more detailed analysis. 您可能会对此问题感兴趣,其中包含更详细的分析。

from your comment 从你的评论

"It doesn't seem to be a great solution. I works, but what if the main is not so trivial? There're a lot of different ways of exiting from my application. Thus, I've got to join my threads manually every time I need it?" “它似乎不是一个很好的解决方案。我的工作,但如果主要不是那么微不足道呢?有很多不同的方式退出我的应用程序。因此,我必须手动加入我的线程每次我需要它?“

how about making A a std::unique_ptr within your main. 如何在你的主要内容中创建一个std :: unique_ptr。 that way, no matter how your main exits, it'll always destroy A before exiting main() and you won't have this problem. 这样,无论你的主要退出方式如何,它总会在退出main()之前销毁A并且你不会遇到这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM