C++ 如何正确地结束一根线?
我的主程序创建了一个线程。该线程初始化一些数据,然后进入“while”循环并运行,直到主程序将控制变量设置为“false”。然后它调用join()witch,无限地阻止整个代码C++ 如何正确地结束一根线?,c++,multithreading,synchronization,C++,Multithreading,Synchronization,我的主程序创建了一个线程。该线程初始化一些数据,然后进入“while”循环并运行,直到主程序将控制变量设置为“false”。然后它调用join()witch,无限地阻止整个代码 bool m_ThreadMayRun; void main(){ thread mythread = thread(&ThreadFunction); //do stuff m_ThreadMayRun = false; mythread.join(); // this blocks
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();
}
- 我是不是遗漏了什么
- 让循环离开主线程的正确解决方案是什么
- 有必要叫join吗
感谢您的帮助对于写入
m_ThreadMayRun
的两个线程,您有一个争用条件。考虑一下如果主线程执行<代码> MythRead MyLun= false,会发生什么情况?code>然后,您希望的线程执行m_ThreadMayRun=true代码>,则有一个无限循环。然而,严格地说,这条推理路线是不相关的,因为当您有一个竞争条件时,您的代码具有未定义的行为
我是不是遗漏了什么
您需要通过使std::atomic
或使用std::mutex
同步对m_ThreadMayRun=false
的访问,并确保在m_ThreadMayRun=true之后执行m_ThreadMayRun=false
代码>
PS对于这种情况,最好使用std::condition\u变量
您有一个两个线程写入m\u ThreadMayRun
的争用条件。考虑一下如果主线程执行<代码> MythRead MyLun= false,会发生什么情况?code>然后,您希望的线程执行m_ThreadMayRun=true代码>,则有一个无限循环。然而,严格地说,这条推理路线是不相关的,因为当您有一个竞争条件时,您的代码具有未定义的行为
我是不是遗漏了什么
您需要通过使std::atomic
或使用std::mutex
同步对m_ThreadMayRun=false
的访问,并确保在m_ThreadMayRun=true之后执行m_ThreadMayRun=false
代码>
PS在这种情况下,最好使用std::condition_变量
问题是对bool m_线程的访问可能会运行代码>不同步,根据C++规则,每个线程可能假设线程之间没有改变。所以你最终会有一场比赛(一种未定义的行为)
要明确意图,请将其设置为原子的
std::atomic<bool> m_ThreadMayRun;
有关内存限制和获取/释放语义的更多详细信息,请参阅以下优秀资源:《C++并发操作》一书和Herb Sutter的演讲。问题在于,访问布尔m_线程可能会运行代码>不同步,根据C++规则,每个线程可能假设线程之间没有改变。所以你最终会有一场比赛(一种未定义的行为)
要明确意图,请将其设置为原子的
std::atomic<bool> m_ThreadMayRun;
有关内存隔离和获取/释放语义的更多详细信息,请参阅以下优秀资源:《C++并发操作》一书和Herb Sutter的演讲。在这里最好使用condvar,以确保m_ThreadMayRun=true
在m_ThreadMayRun=false
@user3365922确实,我想让它保持简单,但我将添加一个注释在主线程中将控制变量设置为true是一种清晰易懂的风格改进。但是在这之后,因为线程只读取变量,所以我看不到竞争条件。我瞎了吗?但如果“原子”是关键,我对这个解决方案很满意。@M.Enke有M_ThreadMayRun=true代码>在从代码中的线程调用的函数中。即使线程只读取,也会有问题。当两个线程访问同一个内存并且至少有一个线程写入它时,就会出现一个争用条件。最好在这里使用condvar来确保m_ThreadMayRun=true
在m_ThreadMayRun=false
@user3365922之后执行,但是我将添加一个注释在主线程中将控制变量设置为true是一种清晰易懂的风格改进。但是在这之后,因为线程只读取变量,所以我看不到竞争条件。我瞎了吗?但如果“原子”是关键,我对这个解决方案很满意。@M.Enke有M_ThreadMayRun=true代码>在从代码中的线程调用的函数中。即使线程只读取,也会有问题。当两个线程访问同一内存,并且至少有一个线程写入ITA时,就会出现争用情况,正如您所看到的joinable()
在这里没有帮助。螺纹是可接合的;你就是这样创造的。(顺便说一句,创建线程可以(而且应该)使用线程我的线程(&ThreadFunction)
)完成,正如您所看到的可连接()
在这里没有帮助。螺纹是可接合的;你就是这样创造的。(顺便说一句,创建线程可以(也应该)使用线程我的线程(&ThreadFunction)
)