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::join
,std::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 之外的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV 分配导致 std::thread::join 中的段错误