如何解决由于我在某些时候使标志变得易失,因此标志的值应更改但是它只在t线程上无限等待
#include <iostream>
#include<thread>
#include <initializer_list>
#include <vector>
#include <future>
#include <time.h>
using namespace std;
class Gadget{
public:
Gadget(){
flag_ = false;
cout<<"Creating new Gadgets"<<endl;
}
void wait(){
while(flag_==false){
cout<<"waiting here...."<<endl;
this_thread::sleep_for(chrono::milliseconds(1000));
}
}
void wake(){
flag_ = true;
}
private:
volatile bool flag_;
};
我正在尝试创建两个线程,并且在检查标志值后一个线程将休眠1秒钟。由于我使标志变得不稳定,所以它应该在某个时候改变。但是程序正在无限等待。
int main() {
Gadget g;
thread t(&Gadget::wait,g);
thread s(&Gadget::wake,g);
t.join();
s.join();
cout<<"Ending the program "<<endl;
return 0;
}
解决方法
volatile
不适用于程序本身更改的变量。它用于在程序的控制范围之外更改的变量-就像直接连接到硬件一样。
但是,您的主要问题是您按值传递了g
,因此这两个线程正在处理原始g
的不同副本。
因此,更改为
std::atomic<bool> flag_;
和
thread t(&Gadget::wait,&g);
thread s(&Gadget::wake,&g);
还值得一提:这两种方法不一定会按照启动它们的顺序运行,因此waiting here....
可能会或可能不会出现。
编辑:
如评论中所述:在等待条件时,通常应使用std::condition_variable
。我已经举了一个例子。我还将线程的开始位置移到了Gadget
中,这使线程在哪个对象上工作更加明显。
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
class Gadget {
public:
Gadget() { std::cout << "Creating new Gadget\n"; }
// new interface for starting threads
std::thread start_wait() { return std::thread(&Gadget::wait,this); }
std::thread start_wake() { return std::thread(&Gadget::wake,this); }
private:
void wait() {
std::unique_lock<std::mutex> ul(mutex_);
std::cout << "wait: waiting here...\n";
// Read about "spurious wakeup" to understand the below:
while(not flag_) cond_.wait(ul);
// or:
// cond_.wait(ul,[this] { return flag_; });
std::cout << "wait: done\n";
}
void wake() {
// simulate some work being done for awhile
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
{ // lock context start
std::lock_guard<std::mutex> lg(mutex_);
flag_ = true;
std::cout << "wake: notifying the waiting threads\n";
} // lock context end
// notify all waiting threads
cond_.notify_all();
}
std::condition_variable cond_;
std::mutex mutex_;
bool flag_ = false; // now guarded by a mutex instead
};
int main() {
Gadget g;
// start some waiting threads
std::vector<std::thread> threads(16);
for(auto& th : threads) th = g.start_wait();
// and one that wakes them up
auto th_wake = g.start_wake();
for(auto& th : threads) th.join();
th_wake.join();
std::cout << "Ending the program\n";
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。