[英]How to end a thread properly?
我的主程序创建了一个线程。 该线程初始化一些数据,然后进入“while”循环并运行,直到主程序将控制变量设置为“false”。 然后它调用 join() 女巫无休止地阻塞整个代码。
bool m_ThreadMayRun;
void main(){
thread mythread = thread(&ThreadFunction);
//do stuff
m_ThreadMayRun = false;
mythread.join(); // this blocks endlessly even when I ask 'joinable' before
}
void ThreadFunction{
initdata();
m_ThreadMayRun=true;
while(m_ThreadMayRun){
//do stuff that can be / has to be done for ever
}
deinitdata();
}
感谢帮助
您有两个线程写入m_ThreadMayRun
的竞争条件。 考虑如果首先主线程执行m_ThreadMayRun = false;
会发生什么然后你创建的线程执行m_ThreadMayRun = true;
,那么你有一个无限循环。 然而,严格来说,这条推理线是无关紧要的,因为当你有竞争条件时,你的代码会有未定义的行为。
我在这里错过了什么吗?
您需要通过使其成为std::atomic<bool>
或使用std::mutex
来同步对m_ThreadMayRun
的访问,并确保在m_ThreadMayRun = false
= true 之后执行m_ThreadMayRun = true;
.
PS对于这种情况,最好使用std::condition_variable
。
问题是访问bool m_ThreadMayRun;
是不同步的,并且根据 C++ 规则,每个线程可以假设它在线程之间没有变化。 所以你最终会遇到一场比赛(一种未定义的行为)。
为了明确意图,使其成为atomic
的。
std::atomic<bool> m_ThreadMayRun;
这样, m_ThreadMayRun
的每个加载/存储都变成了 memory 栅栏,由于原子加载/存储的获取/释放语义,它不仅同步了自己的值,而且还使线程完成的其他工作可见。
尽管线程中的m_ThreadMayRun = true
和设置m_ThreadMayRun = false
之间仍然可能存在小竞争。 任何一个都可以先执行,有时会导致不希望的结果。 为避免这种情况,请在启动线程之前将其初始化为true
。
std::atomic<bool> m_ThreadMayRun;
void main(){
m_ThreadMayRun = true;
thread mythread(&ThreadFunction);
//do stuff
m_ThreadMayRun = false;
mythread.join(); // this blocks endlessly even when I ask 'joinable' before
}
void ThreadFunction{
initdata();
while(m_ThreadMayRun){
//do stuff that can be / has to be done for ever
}
deinitdata();
}
有关 memory 栅栏和获取/释放语义的更多详细信息,请参阅以下优秀资源:《 C++ Concurrency in Action 》一书和 Herb Sutter 的atomic<>
武器谈话。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.