条件变量是允许多个线程相互交流的同步原语。它允许一定量的线程等待(可以定时)另一线程的提醒,然后再继续。条件变量始终关联到一个互斥

定义于头文件 <condition_variable>

condition_variable:

condition_variable 类是同步原语,能用于阻塞一个线程,或同时阻塞多个线程,直至另一线程修改共享变量(条件)并通知 condition_variable 。

有意修改变量的线程必须

  1. 获得 std::mutex (典型地通过 std::lock_guard )
  2. 在保有锁时进行修改
  3. 在 std::condition_variable 上执行 notify_one 或 notify_all (不需要为通知保有锁)

即使共享变量是原子的,也必须在互斥下修改它,以正确地发布修改到等待的线程。

任何有意在 std::condition_variable 上等待的线程必须

  1. 获得 std::unique_lock<std::mutex> ,在与用于保护共享变量者相同的互斥上
  2. 执行 wait 、 wait_for 或 wait_until ,等待操作自动释放互斥,并悬挂线程的执行
  3. condition_variable 被通知时,时限消失或虚假唤醒发生,线程被唤醒,且自动重获得互斥。之后线程应检查条件,若唤醒是虚假的,则继续等待

代码:

 #include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std; std::mutex m;
std::condition_variable cv;
string data;
bool ready = false;
bool processed = false; void worker_thread() {
//等待直至 main() 发送数据
std::unique_lock<std::mutex> lk(m);//拥有mutex,并调用mutex.lock()对其上锁
cv.wait(lk, []{return ready;});//等价于 while(!ready) cv.wait(lk);
//在调用 wait 时会自动执行 lk.unlock()
//当 wait 被其它线程唤醒时,锁会自动恢复 wait 之前的状态 //等待后,我们占有锁
cout << "worker thread is processing data\n";
data += " after processing"; //发送数据回 main
processed = true;
cout << "worker thread sigals data processing completed\n"; lk.unlock();//通知前手动解锁,以避免等待线程再阻塞
cv.notify_one();
} int main(void) {
std::thread worker(worker_thread); data = "Example data";
//发送数据到worker线程
{
std::lock_guard<std::mutex> lk(m);
ready = true;
cout << "main() sigals data ready for processing\n";
}
cv.notify_one(); //等候worker
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return processed;});//等价于while(!processed) cv.wait(lk)
}
cout << "Back in main(), data = " << data << '\n'; worker.join(); // 输出:
// main() sigals data ready for processing
// worker thread is processing data
// worker thread sigals data processing completed
// Back in main(), data = Example data after processing return ;
}

注意:虚假唤醒问题 https://segmentfault.com/q/1010000010421523/a-1020000010457503

https://blog.csdn.net/shizheng163/article/details/83661861

condition_variable_any 类是 std::condition_variable 的泛化。相对于只在 std::unique_lock<std::mutex> 上工作的 std::condition_variable , condition_variable_any 能在任何满足基础可锁 (BasicLockable) 要求的锁上工作,操作和 std::condition_variable 完全相同

c++多线程基础4(条件变量)的更多相关文章

  1. linux多线程同步pthread_cond_XXX条件变量的理解

    在linux多线程编程中,线程的执行顺序是不可预知的,但是有时候由于某些需求,需要多个线程在启动时按照一定的顺序执行,虽然可以使用一些比较简陋的做法,例如:如果有3个线程 ABC,要求执行顺序是A-- ...

  2. linux C++ 多线程使用pthread_cond 条件变量

    1. 背景 多线程中经常需要使用到锁(pthread_mutex_t)来完成多个线程之间的互斥操作. 但是互斥锁有一个明显到缺点: 只有两种状态,锁定和非锁定. 而条件变量则通过允许线程阻塞并等待另一 ...

  3. Linux多线程编程的条件变量

    在stackoverflow上看到一关于多线程条件变量的问题,题主问道:什么时候会用到条件变量,mutex还不够吗?有个叫slowjelj的人做了很好的回答,我再看这个哥们其他话题的一些回答,感觉水平 ...

  4. 练习生产者与消费者-PYTHON多线程中的条件变量同步-Queue

    以前练习过,但好久不用,手生,概念也生了, 重温一下.. URL: http://www.cnblogs.com/holbrook/tag/%E5%A4%9A%E7%BA%BF%E7%A8%8B/ ~ ...

  5. Linux 多线程编程—使用条件变量实现循环打印

    编写一个程序,开启3个线程,这3个线程的ID分别为A.B.C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示:如:ABCABC….依次递推. 使用条件变量来实现: #inc ...

  6. 多线程编程中条件变量和的spurious wakeup 虚假唤醒

    1. 概述 条件变量(condition variable)是利用共享的变量进行线程之间同步的一种机制.典型的场景包括生产者-消费者模型,线程池实现等. 对条件变量的使用包括两个动作: 1) 线程等待 ...

  7. python多线程编程5: 条件变量同步-乾颐堂

    互斥锁是最简单的线程同步机制,Python提供的Condition对象提供了对复杂线程同步问题的支持.Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还 ...

  8. Java多线程基础——对象及变量并发访问

    在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...

  9. java多线程技术之条件变量

    上一篇讲述了并发包下的Lock,Lock可以更好的解决线程同步问题,使之更面向对象,并且ReadWriteLock在处理同步时更强大,那么同样,线程间仅仅互斥是不够的,还需要通信,本篇的内容是基于上篇 ...

随机推荐

  1. php使用substr中文乱码问题

    周天的时候对网站 https://www.javasec.cn 进行bug修复和功能更新,其中遇到一个比较有意思的小问题: 问题: 网站的置顶推荐中,有文本略缩.但是无论怎么修改最后一个字符始终现实为 ...

  2. hadoop 小知识点

    ------------------------------------------- 配置hadoop的最小blocksize,必须是512的倍数. [hdfs-site.xml] dfs.name ...

  3. 【转】VS 安全开发生命周期(SDL)检查

    前面在学习使用google的protobuf时在VS2012中一直无法编译编译通过,经过查找一些资料原来发现,并不是protobuf的问题,而是自己在使用VS2012时,没有完全了解VS2012的强大 ...

  4. spring中二个重要点

    spring核心主要两部分: (1)aop: 面向切面编程,扩展功能不是修改源代码实现 (2)ioc: 控制反转

  5. saltstack系列(五)——zmq扩展(一)

    问题 假设我们的一个客户端既有pull又有sub,他们两个都需要接收消息,该如何协调呢,毕竟,当一个socket要收消息的时候,函数recv是阻塞的,所以,我们第一个思路是不让它阻塞? 实例代码: # ...

  6. NetworkView

    [游戏Server中Server的类别] There are two common and proven approaches to structuring a network game which ...

  7. AntD02 Table组件的使用

    1 前提准备 1.1 创建一个angular项目 1.2 将 Ant Design 整合到 Angular 项目中 1.3 官方文档 点击前往 2 简单使用 <nz-table #rowSele ...

  8. Win10系统优化/设置脚本

    Win10系统优化/设置脚本 用了很长时间win10了,用的过程中,发现了一些问题,关于系统基本的优化,和个人的使用习惯设置等等,做成了一个脚本,可以一键设置win10的系统设置,结合DWS对Win1 ...

  9. 367. Valid Perfect Square判断是不是完全平方数

    [抄题]: Given a positive integer num, write a function which returns True if num is a perfect square e ...

  10. 13-爬取百度贴吧中的图片(python+xpath)

    通过xpath分析页面,爬取页面中的图片: #_*_ coding: utf-8 _*_ ''' Created on 2018年7月15日 @author: sss function: 使用xpat ...