简体   繁体   English

等待std :: thread完成

[英]Waiting for a std::thread to finish

I am trying to clean up gracefully on program termination, so I'm calling join() on a std::thread to wait for it to finish. 我试图在程序终止时优雅地清理,所以我在std::thread上调用join()来等待它完成。 This simply seems to block the main thread forever, but I don't understand why, because the worker thread is an (almost) empty loop like this: 这似乎只是永远阻止主线程,但我不明白为什么,因为工作线程是一个(几乎)空循环,如下所示:

void GameLoop::Run()
{
    while (run)
    {
        //  Do stuff... 
    }   
    std::cout << "Ending thread...\n";
}

I'm setting run to false before join ing, of course. 我设置run为false之前join ,当然ING。 Now, I'm suspecting it's got something to do with it being a member function and being called upon object destruction . 现在,我怀疑它与它是一个成员函数并被称为对象破坏有关 I'm creating the thread like this: runThread.reset(new thread(&GameLoop::Run, this)); 我正在创建这样的线程: runThread.reset(new thread(&GameLoop::Run, this)); , where runThread is unique_ptr<std::thread> and a member of GameLoop . ,其中runThreadunique_ptr<std::thread>GameLoop的成员。 The join() call comes in the destructor of the GameLoop object. join()调用来自GameLoop对象的析构函数。

Maybe the loop thread cannot finish if its object is in the process of being destroyed? 如果它的对象正在被破坏的过程中,循环线程可能无法完成? According to the debugger the loop thread lingers on in the dark depths of msvcr120d.dll . 根据调试器,循环线程在msvcr120d.dll的黑暗深处msvcr120d.dll If so, how would you handle it? 如果是这样,你会如何处理它?

Beware: new to std::thread here! 注意:这里是std::thread新手!

Update: This is my call to join in the destructor: 更新:这是我加入析构函数的调用:

run = false;
if (runThread->joinable())
{
    runThread->join();
}

Update 2: If I remove the join() I get an exception raised by ~thread() ! 更新2:如果我删除了join()我得到了~thread()引发的异常!

Of course, when you join a thread that doesn't cause the thread to terminate. 当然,当你join一个不会导致线程终止的线程时。 It simply blocks until that thread dies of natural (or unnatural) causes. 它只是阻塞,直到该线程死于自然(或不自然)的原因。

In order to clean up a multithreaded application gracefully, you need to somehow tell the worker thread that it is time to die, and then wait for the death to happen. 为了优雅地清理多线程应用程序,您需要以某种方式告诉工作线程是时候死亡,然后等待死亡发生。 The "wait for death to happen" part is what join is for. “等待死亡发生”的部分是join目的。

Ahh, apparently there's a bug in the runtime library. 啊,显然运行时库中存在一个错误。 Threads are not ended successfully in destructors of static objects according to this question . 根据这个问题,线程不能在静态对象的析构函数中成功结束。 My GameLoop is a non-static object contained in a static GameSystem . 我的GameLoop是一个包含在静态GameSystem的非静态对象。 I'll check whether this is true and update. 我会检查这是否属实并更新。

Yep, confirmed. 是的,确认。 Just my luck to hit a bug on first use! 只是我的运气,在第一次使用时遇到错误!

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

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