std::condition_variable

2023-10-26

std::condition_variable

std::condition_variable,是C++11提供的条件变量,可用于同时阻塞一个线程或多个线程。一般的,生产者线程利用支持std::mutex的std::lock_guard/std::unique_lock修改共享变量后,并通知condition_variable。消费者线程获取同一个std::mutex(std::unique_lock所持有),并调用std::condition_variable的wait, wait_for, or wait_until。wait操作会释放互斥量,同时挂起该线程。当条件变量收到通知、超时到期或发生虚假唤醒时,线程被唤醒,互斥量也被原子地重新获取。需要注意的是,如果是虚假唤醒,线程应该检查条件并继续等待,以保证业务的正确性。

std::condition_variable::wait()

unconditional (1) void wait( std::unique_lockstd::mutex& lock );
predicate (2) template< class Predicate >
void wait( std::unique_lock< std::mutex >& lock, Predicate stop_waiting );

wait() 有两个重载,第二个算是一个语法糖,可用于在等待特定条件变为真时忽略虚假唤醒。相当于:

while (!stop_waiting()) {
    wait(lock);
}

注意:lock必须在wait()前调用,可以用来守护访问stop_waiting()。wait(lock)返回后会重新获取该lock。

示例:

#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
 
std::mutex mtx;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;
 
void worker_thread()
{
    // Wait until main() sends data
    std::unique_lock lock(mtx);
    cv.wait(lock, []{return ready;});
 
    // after the wait, we own the lock.
    std::cout << "Worker thread is processing data\n";
    data += " after processing";
 
    // Send data back to main()
    processed = true;
    std::cout << "Worker thread signals data processing completed\n";
 
    // Manual unlocking is done before notifying, to avoid waking up
    // the waiting thread only to block again (see notify_one for details)
    lock.unlock();
    cv.notify_one();
}
 
int main()
{
    std::thread worker(worker_thread);
 
    data = "Example data";
    // send data to the worker thread
    {
        std::lock_guard lock(mtx);
        ready = true;
        std::cout << "main() signals data ready for processing\n";
    }
    cv.notify_one();
 
    // wait for the worker
    {
        std::unique_lock lock(mtx);
        cv.wait(lock, []{return processed;});
    }
    std::cout << "Back in main(), data = " << data << '\n';
 
    worker.join();
}

输出:

main() signals data ready for processing
Worker thread is processing data
Worker thread signals data processing completed
Back in main(), data = Example data after processing
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

std::condition_variable 的相关文章

  • C++ win32设置光标位置

    我知道要使用哪个功能 但我无法让它正常工作 我用了SetCursorPos 唯一的问题是它将光标设置为屏幕坐标而不是窗口坐标 我也尝试过ScreenToClient 但它并没有起作用 这是我的代码 pt x 113 pt y 280 Scr
  • 如何在C++、Qt、QML、Blackberry 10 Cascades Beta 3 SDK中制作图表/图形(如折线图、条形图、圆形图)等?

    我需要知道如何在 Blackberry 10 Cascades Beta 3 SDK QML Qt C 中制作图表 图表 如果有人可以向我展示一个例子或向我指出一些可以告诉我如何做到这一点的东西 我将不胜感激 您应该查看 QChart js
  • Microsoft Graph API 授权错误:无效受众

    我知道这是一个很长的问题 但如果有人能与我分享他们的想法或经验 我真的很感激 因为我已经解决这个问题几天了 现在正在尝试很多事情 我有一个 ASP Net Core 3 1 Web API 应用程序和一个 ASP NET Core 3 1
  • 是否有一种快速替代方法可以从 XNA 中的位图对象创建 Texture2D?

    我环顾四周 发现从位图创建Texture2D的唯一方法是 using MemoryStream s new MemoryStream bmp Save s System Drawing Imaging ImageFormat Png s S
  • 如何更改 GridView 内 ListViewItemPresenter 中的 SelectedBackground

    我在 SubSection 中有一个 Clickable Gridview
  • 如何在 Xamarin.Forms 中强制使用浅色模式?

    我的应用程序的 UI 设计为在灯光模式下使用 但如果手机的默认主题是深色模式 我的应用程序也会切换到深色模式 并且 UI 看起来很垃圾 所以我想强制我的应用程序使用灯光模式 我怎样才能做到这一点 In my app xaml我使用的文件Us
  • 如何设置属性选择器的值 Expression>

    我需要使用模式工厂的想法将 Person 类实体中的实体属性 Address 与 FactoryEntities 类中的表达式 linq 相关联 看看这就是我所拥有的并且我想要做的 Address address new Address a
  • 在 Asp.net Web API 中处理 CORS 预检

    我的架构中有三个应用程序 它们位于同一服务器上 但具有不同的端口号 A Token Application port 4444 Asp net WebApi B API Application port 3333 Asp net WebAp
  • C++ 中的静态虚函数

    我有一个基类和一个派生类 我想更改基函数 同时保持它们静态 因为它们应该作为静态传递给其他函数 我怎样才能做到这一点 ATL 框架通过将基类设为模板 然后让派生类将其类类型作为模板参数传递 从而绕过了无虚拟静态的限制 然后 基类可以在需要时
  • 如何对具有无效值的属性使用 JSON.net 的默认值

    我正在使用 Newtonsoft JSON 库来反序列化来自 Web 服务的响应 问题是某些字段包含无效值 例如 一条记录上的一个字段包含一个 T 表示该字段应该是数字 我想做的是将无效字段的值设置为 null 或其他默认值 我的所有属性都
  • Windows Phone 8.1 应用程序多语言

    我正在使用 Visual Studio 2015 在 SilverLight 中创建 Windows Phone 应用程序 8 1 我正在用英语和阿拉伯语创建多语言应用程序 为此 我在项目中创建了 Strings 文件夹 其中包含 en U
  • 更改子进程中的 iostream

    现在 我正在开发一个项目 其中我需要启动一个子进程来使用 C 在 Linux 中执行一个新程序 并且我需要重定向标准输入和输出 就像在 C 中一样 它们是cin and cout 到一个文件 这意味着在子进程中 标准输入和输出都是文件 子进
  • 产量回报延迟迭代问题

    我知道yield return 利用了延迟加载 但我想知道我是否可能滥用迭代器或者很可能需要重构 我的递归迭代器方法返回给定的所有祖先PageNode包括pageNode itself public class PageNodeIterat
  • 如何使用 GCC 在 C 上编译库?

    我用这些文件创建了一个库pila h and pila c 我编译文件pila c with gcc pila c c这个库运行良好 我已经测试过了 然后我又做了一个图书馆 这个库有文件pila funciones extra h and
  • 宏中 do { } while(0) 与 ({ }) 的优点?

    Stack Overflow 上有很多关于使用的问题do while 0 在宏中 但这有点不同 我明白为什么do while 0 用于将多行代码包装在宏扩展中 但我经常看到另一种形式 The form 的优点是它是一个表达式并且可以有 返回
  • C++ 头文件包含

    我正在开发一个项目 每个头文件都有一个预处理器包含防护 我的包含是这样的 文件 gt 包含 main cpp gt header h 字符 h header h gt 矢量 iostream DataFiles h Character h
  • C# - 平移光标

    我正在 PictureBox 控件中实现大图像的平移 并且设置适当的方向平移光标没有问题 但是 我似乎找不到用于平底锅原点的图像 内部带有箭头的圆圈 我在哪里可以找到它 我觉得image您正在寻找的内容未包含在框架中 每个应用程序都使用自己
  • 为什么我能够使用无效的类指针进行函数调用

    在下面的代码片段中 虽然指针未初始化 但调用仍然成功 temp ptr ptr gt func2 是C 语言特性的问题 还是VC 6编译器的作弊 class temp public temp a 9 int func1 return a b
  • 我该怎么做才能完全关闭与mcu的tcpClient连接?

    我现在正在研究与 ESP32 中运行的 tcp 服务器的 tcp 套接字连接 通信工作正常 但我无法关闭连接 在搜索关闭 重置 tcpClient 上的解决方案后 似乎关闭 tcpClient 的正确方法应该是 tcpClient GetS
  • XslCompiledTransform 和自定义 XmlUrlResolver:“具有相同键的条目已存在”

    有没有办法调试由自定义 XmlUrlResolver 从数据库加载的 XSLT 文档 或者有人知道下面的错误消息是关于什么的吗 我有一个导入通用 xslt 文档的 XSLT 样式表

随机推荐

  • STM32配置时钟系统流程(固件库/外设标准库)

    前提 STM32F10x系列固件库 标准外设库 前言 固件库帮我们写好了 时钟系统 时钟树 的配置函数 该函数也不需要我们去调用 只要正确包含了STM32的启动文件 s文件 就行 s启动文件调用执行了时钟配置函数 先于main函数执行 s启
  • “钢铁侠”大战“机器人”!马斯克称「笼中格斗」将在 X 上直播,小扎应战:8 月 26 日如何?...

    由马斯克和扎克伯格领衔 随后引爆全网讨论的 约架 已过去快两个月 先是约定在拉斯维加斯来一场 笼中格斗 接着网友看热闹不嫌事大的做起了预告海报 最后由马斯克母亲出面叫停 当大家以为格斗一事要不了了之时 马斯克再次发声 要打 准备在 X 上直
  • 【Android】拾物App期末作业

    一 期末作业题目 校园失物 拾物APP 二 实施目的 通过本实训 使受训者可以深入理解Android相关技术 并将所学知识应用到实际的中等规模的程序设计中 同时 通过本实训 受训者可以拓展Android相关的知识 提升受训者的能力 三 实施
  • java中JDK JRE JVM的关系

    1 1 软件开发介绍 程序是为了模拟现实世界 解决显示问题而使用计算机语言编写的一系列有序的指令集合 软件 即一系列按照特定顺序组织的计算机数据和指令集合 有系统软件和应用软件之分 人机交互方式 图形化界面 GUI 命令行方式 CLI 常用
  • IO作业day5

    1 gt 使用两个线程完成两个文件的拷贝 主线程拷贝前一半内容 子线程拷贝后一半内容 并且主线程要阻塞回收子线程资源 2 gt 使用三个进程完成两个文件的拷贝 主线程拷贝前三分之一 子线程1拷贝中间三分之一 子线程2拷贝后三分之一 主线程要
  • 使用 Android 开发 MQTT 客户端

    MQTT 代表消息队列遥测传输 它是一种功能强大的消息传输协议 主要用于机器对机器 M2M 和物联网 IoT 通信上下文 MQTT 在这些情况下是首选 因为它易于实施 并且非常适合资源有限的设备 在本文中 我们将开发一个使用 MQTT 协议
  • c语言结构体简单试题,C语言6结构体练习题6

    第六章 结构体 1 下面对结构变量的叙述中错误的是 A 相同类型的结构变量间可以相互赋值 B 通过结构变量 可以任意引用它的成员 C 结构变量中某个成员与这个成员类型相同 的简单变量间可相互赋值 D 结构变量与简单变量间可以赋值 2 有枚举
  • 如何实现算法中的公平性

    机器学习的公平性问题近几年受到越来越多的关注 该领域出现了一些新的进展 机器学习训练在涉及到性别 种族等与人相关的敏感属性时 常常会由于统计性偏差 算法本身甚至是人为偏见而引入歧视性行为 由此 为消除差别影响 改进机器学习公平性 主要途径包
  • 在jsp中实现表格内设置滚动框

    当我们在页面中需要放置多条数据时 滚动框则将是一个十分不错的选择 在需要加入滚动框的表格内设置标签 table tbody style display block tbody table
  • 利用Python实现卷积神经网络的可视化

    对于深度学习这种端到端模型来说 如何说明和理解其中的训练过程是大多数研究者关注热点之一 这个问题对于那种高风险行业显得尤为重视 比如医疗 军事等 在深度学习中 这个问题被称作 黑匣子 Black Box 如果不能解释模型的工作过程 我们怎么
  • C#网络编程,多个客户端连接服务器端并发送消息

    最近学习进度到了C 网络编程 在学习这一章节的知识点 写了一些小demo 此次发表的为服务器监听端口 和多个客户端连接 获取多个客户端发来的消息 服务器端代码 using System Net using System Net Socket
  • SQL Server迭代求和

    drop table t geovindu create table t geovindu xid int IDENTITY 1 1 price money DebitCredit VARCHAR 2 adate datetime defa
  • Android学习之 Scroller的介绍与使用

    类概述 Android里Scroller类是为了实现View平滑滚动的一个Helper类 通常在自定义的View时使用 在View中定义一个私有成员mScroller new Scroller context 设置mScroller滚动的位
  • 微服务工程搭建过程中的注意点

    1 父工程pom xml文件 1 父工程的maven坐标 2 packaging使用pom 原因 在Spring Cloud微服务工程中 通常会采用多模块的方式进行开发 父工程的pom文件中的packaging标签设置为pom 是因为父工程
  • Spring Framework 入门(一)

    Spring Framework各模块作用介绍 可以参考spring framework的github项目 源码地址 https github com spring projects spring framework 下面我们分别了解下各个
  • SQL所有关键字及其作用:

    以下是MySQL的所有关键字及其作用 ADD 在表中添加新的列或索引 ALL 返回满足条件的所有行 包括重复行 ALTER 修改表的结构 如添加 修改或删除列 ANALYZE 分析并收集表的统计信息 用于优化查询 AND 用于多条件查询的逻
  • wedo2.0编程模块介绍_西门子S7-200 SMART硬件和编程软件简介

    前文给大家简单的讲介绍了一下PLC编程涉及的一些概念型知识 本文开始实践 今天带来的是SIMATIC S7 200 SMART硬件和编程软件简介 SIMATIC S7 200 SMART 是西门子公司经过大量市场调研 为中国客户量身定制的一
  • Java 多线程 --- 按序打印

    Java 多线程 按序打印 方法1 控制变量 使用volatile关键字优化 方法2 synchronized wait notifyAll 方法3 信号量 给你一个类 public class Foo public void first
  • 【深度学习】参数量、模型大小、显存

    对于一个深度学习神经网络来说 其通常包含很多卷积层 用于不断提取目标的特征 或对目标进行最终定位或者分类 1 数据存储精度与存储空间 在深度学习神经网络中 最常见的数据格式是float32 占4个字节 Byte 类似地 float16 占2
  • std::condition_variable

    std condition variable std condition variable 是C 11提供的条件变量 可用于同时阻塞一个线程或多个线程 一般的 生产者线程利用支持std mutex的std lock guard std un