C++条件变量

1、有什么用:html

当须要死循环判断某个条件成立与否时【true or false】,咱们每每须要开一个线程死循环来判断,这样很是消耗CPU。使用条件变量,可让当前线程wait,释放CPU,若是条件改变时,咱们再notify退出线程,再次进行判断。this

2、其余解释spa

想要修改共享变量(即“条件”)的线程必须:
1. 得到一个std::mutex
2. 当持有锁的时候,执行修改动做
3. 对std::condition_variable执行notify_one或notify_all(当作notify动做时,没必要持有锁)

即便共享变量是原子性的,它也必须在mutex的保护下被修改,这是为了可以将改动正确发布到正在等待的线程。

任意要等待std::condition_variable的线程必须:
1. 获取std::unique_lock<std::mutex>,这个mutex正是用来保护共享变量(即“条件”)的
2. 执行wait, wait_for或者wait_until. 这些等待动做原子性地释放mutex,并使得线程的执行暂停
3. 当得到条件变量的通知,或者超时,或者一个虚假的唤醒,那么线程就会被唤醒,而且得到mutex. 而后线程应该检查条件是否成立,若是是虚假唤醒,就继续等待。线程

【注: 所谓虚假唤醒,就是由于某种未知的罕见的缘由,线程被从等待状态唤醒了,但其实共享变量(即条件)并未变为true。所以此时应继续等待】code

 https://en.cppreference.com/w/cpp/thread/condition_variablehtm

3、代码blog

std::deque<int> q; std::mutex mu; std::condition_variable cond; void function_1() //生产者 { int count = 10; while (count > 0) { std::unique_lock<std::mutex> locker(mu); q.push_front(count); locker.unlock(); cond.notify_one(); // Notify one waiting thread, if there is one. std::this_thread::sleep_for(std::chrono::seconds(1)); count--; } } void function_2() //消费者 { int data = 0; while (data != 1) { std::unique_lock<std::mutex> locker(mu); while (q.empty()) cond.wait(locker); // Unlock mu and wait to be notified data = q.back(); q.pop_back(); locker.unlock(); std::cout << "t2 got a value from t1: " << data << std::endl; } } int main() { std::thread t1(function_1); std::thread t2(function_2); t1.join(); t2.join(); return 0; }

 

核心:队列

①、在消费者里判断队列是否为空后,若是不为空则wait,等待生产者发送notify信号作用域

②、在生产者那里,若是生产了任务,则发送notify信号,告诉消费者能够试图退出wait,判断队列是否为空,若是有任务则调度处理任务,若是仍是空则说明这次notify是错误的,多是其余地方发出来干扰的,生产者继续wait。it

③、流程:

软件开启,生成消费者线程消费队列,应该是一个while循环,在循环里获取锁,再来一个while循环判断条件,若是条件不成立则wait,wait会自动释放锁;

此时消费者已经没有锁了,在生产者线程里,获取锁,而后往里面加任务,退出做用域释放锁,而后notify告知消费者退出wait,消费者从新获取锁,而后从队列里取任务;

整个过程,生产者加任务时生产者持有锁,消费者取任务时消费者持有锁。

 

对于此处补充:https://www.cnblogs.com/judes/p/11132918.html

相关文章
相关标签/搜索