C++ 在类中的成员更改时终止线程中的循环
我有一个类在一个单独的线程上运行一个循环,当我将一个成员的值更改为false时,我希望它中断:C++ 在类中的成员更改时终止线程中的循环,c++,multithreading,C++,Multithreading,我有一个类在一个单独的线程上运行一个循环,当我将一个成员的值更改为false时,我希望它中断: #include <iostream> #include <thread> #include <future> #include <chrono> #include <functional> #include <atomic> class A { public: void ChangeLoop(){ lo
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
#include <functional>
#include <atomic>
class A
{
public:
void ChangeLoop(){
loop = !loop;
if(loop){
std::future<void> fi = std::async(std::launch::async, &A::RunLoop, this, std::ref(loop));
}
}
void RunLoop(std::atomic<bool> &loop_ref){
while(loop_ref){
emit(loop_ref);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
private:
std::atomic<bool> loop {false};
std::mutex emit_mutex;
template<class...Ts> void emit(Ts&&...ts){
auto lock = std::unique_lock<std::mutex>(emit_mutex);
using expand = int[];
void(expand{
0,
((std::cout << ts << "\n"), 0)...
});
}
};
int main(){
A a;
a.ChangeLoop();
std::this_thread::sleep_for(std::chrono::seconds(2));
a.ChangeLoop();
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
甲级
{
公众:
void ChangeLoop(){
循环=!循环;
如果(循环){
std::future fi=std::async(std::launch::async,&A::RunLoop,this,std::ref(loop));
}
}
void RunLoop(标准::原子循环和循环参考){
while(循环参考){
发射(环路参考);
std::this_线程::sleep_for(std::chrono::毫秒(50));
}
}
私人:
std::原子循环{false};
std::互斥体发出互斥体;
模板无效发射(Ts&…Ts){
自动锁定=标准::唯一锁定(发出互斥);
使用expand=int[];
空(展开){
0,
((std::cout既然您已经找到了问题的有效解决方案,我只想指出为什么std::async
不是正确的选择
从网上参考:
如果从std::async获取的std::future未从引用中移动或绑定到引用,则std::future的析构函数将在完整表达式的末尾阻塞,直到异步操作完成。
因此,这里有std::future
阻塞的析构函数,因为RunLoop
线程由于其while
循环而从未完成执行
即使std::async
中的返回值在ChangeLoop
中被忽略,并且没有分配给std::future
时,这也是正确的
<有些C++专家说,<代码> STD:由<代码> STD::AcYNC/<代码>产生的未来< /代码>不应该阻止。这是萨特的一个例子。
但是现在,评论中提出的解决方案(使用std::detach
)是正确的选择。std::async
在这里是错误的选择。将std::thread
与detach()
结合使用。更改std::future fi=std::async(std::launch::async,&A::RunLoop,this,std::ref(loop));
tostd::thread(&A::RunLoop,this,std::ref(loop)).detach()我希望你得到的点<代码> > STD::AsYNC/<代码>不是正确的选择。谢谢@ OZ17,这对我起了作用!谢谢@ P.W.在阅读了你提供的信息并在C++线程上观看Bo Qian的视频之后,我明白了为什么我需要使用STD::线程带DATAT。在这种情况下,我们将使用ch。
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
#include <functional>
#include <atomic>
class A
{
public:
void ChangeLoop(){
loop = !loop;
if(loop){
std::future<void> fi = std::async(std::launch::async, &A::RunLoop, this);
}
}
void RunLoop(){
while(loop){
emit(loop);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
private:
std::atomic<bool> loop {false};
std::mutex emit_mutex;
template<class...Ts> void emit(Ts&&...ts){
auto lock = std::unique_lock<std::mutex>(emit_mutex);
using expand = int[];
void(expand{
0,
((std::cout << ts << "\n"), 0)...
});
}
};
int main(){
A a;
a.ChangeLoop();
std::this_thread::sleep_for(std::chrono::seconds(2));
a.ChangeLoop();
return 0;
}