std::scoped_lock` 和 `std::lock() ,condition_variable,promise

std::scoped_lockstd::lock() 同时锁多个mutex

std::scoped_lockstd::lock() 都是 C++ 标准库中用于管理多个 std::mutex 对象的工具,但它们在使用方式和一些方面上存在一些区别。以下是它们的主要区别:

  1. 用法差异:

    • std::scoped_lock 是一个模板,你需要将要锁定的所有 std::mutex 作为参数传递给它的构造函数。它会在构造时锁定所有提供的互斥量,而在析构时自动释放这些锁。
    std::mutex mtx1;
    std::mutex mtx2;{std::scoped_lock lock(mtx1, mtx2);  // 锁定 mtx1 和 mtx2// 在这个作用域内,mtx1 和 mtx2 都已经被成功锁定
    }
    // 在这个作用域结束时,mtx1 和 mtx2 会被解锁支持RAII
    
    • std::lock() 是一个函数,接受任意数量的 std::mutex 参数,并在一次函数调用中尽可能地同时锁定所有提供的互斥量。这可以避免死锁,并且比分别调用 std::lock_guardstd::unique_lock 更高效。
    std::mutex mtx1;
    std::mutex mtx2;std::lock(mtx1, mtx2);  // 锁定 mtx1 和 mtx2
    //需要手动解锁,不支持RAII
    
  2. 死锁避免:

    • std::lock() 在一次函数调用中尝试锁定所有提供的互斥量,如果无法同时锁定,会产生 std::system_error 异常。因此,在使用 std::lock 时,确保所有互斥量都是可锁定的,否则会导致程序异常终止。
    • std::scoped_lock 在构造时就锁定了所有提供的互斥量,如果无法同时锁定会产生 std::system_error 异常。因此,在使用 std::lock 时,确保所有互斥量都是可锁定的,否则会导致程序异常终止。

在C++中,条件变量(Condition Variable)是用于线程间同步的一种机制。条件变量通常与互斥锁结合使用,用于实现线程的等待和唤醒机制,以确保线程在满足某些条件时才能执行。

常用的条件变量相关的类有 std::condition_variablestd::condition_variable_any。以下是简要介绍和使用条件变量的基本模式:

条件变量

std::condition_variable 使用示例:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool dataReady = false;void producer() {// 模拟生产数据std::this_thread::sleep_for(std::chrono::seconds(2));// 加锁,修改共享状态std::unique_lock<std::mutex> lock(mtx);dataReady = true;// 通知等待的线程cv.notify_one();
}void consumer() {std::unique_lock<std::mutex> lock(mtx);// 等待条件变量通知cv.wait(lock, [] { return dataReady; });// 消费数据std::cout << "Data consumed." << std::endl;
}int main() {std::thread producerThread(producer);std::thread consumerThread(consumer);producerThread.join();consumerThread.join();return 0;
}

在这个示例中,std::condition_variablestd::mutex 一起使用,cv.wait(lock, predicate) 用于等待条件变量的通知,而 cv.notify_one() 用于通知等待的线程。

要点:

  1. std::condition_variable 需要与 std::mutex 一起使用,以确保在条件变量上进行操作时的线程安全性。
  2. std::unique_lock 提供了更灵活的锁定和解锁操作,可以在需要的时候手动解锁,例如在等待条件变量时。
  3. cv.wait(lock, predicate) 中的 predicate 是一个可选的谓词函数,用于检查条件是否满足,如果条件不满足,则继续等待。

条件变量的正确使用可以确保线程在适当的时候等待和唤醒,以避免不必要的轮询和提高程序的效率。

线程异步和通信

std::promise异步调用

std::promisestd::future 是 C++11 标准库中提供的两个工具,用于在多线程之间传递数据或者实现异步操作。

  1. std::promise:

    • std::promise 用于在一个线程中存储一个值,然后在另一个线程中通过 std::future 获取这个值。一个 std::promise 对象关联一个 std::future 对象,后者可以在其他线程中被用来获取由 std::promise 对象设置的值。

    • std::promiseset_value 成员函数只能成功调用一次。一旦调用 set_valuestd::promise 对象就变得不能再用于设置新的值。

    • std::future 提供访问异步操作结果的机制 get() 阻塞等待promise set_value 的值

    • 示例:

      #include <iostream>
      #include <future>void setValue(std::promise<int>& prom) {prom.set_value(42);
      }int main() {std::promise<int> myPromise;std::future<int> myFuture = myPromise.get_future();std::thread t(setValue, std::ref(myPromise));t.join();int result = myFuture.get();std::cout << "Received value from promise: " << result << std::endl;return 0;
      }
      

    std::promise 用于在一个线程中设置值,然后通过与关联的 std::future 在另一个线程中获取这个值。std::future 则用于获取异步任务的结果。

  2. std::future:

    • std::future 用于从异步任务中获取值。std::future 对象可以通过与 std::promise 关联,或者通过 std::asyncstd::packaged_task 等方式创建。

    • 示例:

      #include <iostream>
      #include <future>int calculate() {return 21;
      }int main() {std::future<int> myFuture = std::async(std::launch::async, calculate);int result = myFuture.get();std::cout << "Result from future: " << result << std::endl;return 0;
      }
      

需要注意的是,std::promisestd::future 通常是成对使用的,但也可以通过其他方式创建 std::future 对象,比如使用 std::async

总体来说,std::promisestd::future 是 C++ 中实现简单异步编程的一种方便机制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/597735.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git 对项目更新的时候提示错误 repository not owned by current user

遇到 Git 提示的错误信息为&#xff1a;repository not owned by current user 上图显示的是错误的信息。 问题和解决 出现上面错误信息的原因是当前文件夹的权限和 Git 的执行权限不一直导致的。 我们的问题是我们希望在网盘上使用 Git 更新克隆后的代码&#xff0c;但登录…

React Hook 原理,及如何使用Hook

一、 Hook使用规则 只在最顶层使用Hook 不要在循环&#xff0c;条件或嵌套函数中调用Hook&#xff1b; 只在组件函数和自定义hook中调用Hook Q1 &#xff1a; 为什么 hook 不能 在循环&#xff0c;条件或嵌套函数中调用Hook &#xff1f; A1&#xff1a; 因为这跟React的…

使用Kafka与Spark Streaming进行流数据集成

在当今的大数据时代&#xff0c;实时数据处理和分析已经变得至关重要。为了实现实时数据集成和分析&#xff0c;组合使用Apache Kafka和Apache Spark Streaming是一种常见的做法。本文将深入探讨如何使用Kafka与Spark Streaming进行流数据集成&#xff0c;以及如何构建强大的实…

【智慧地球】星图地球 | 星图地球超算数据工场

当前空天信息处理涉及并发并行的大量计算问题&#xff0c;需要高性能计算、智能计算联合调度&#xff0c;以此来实现多算力融合&#xff1b;而我国算力产业规模快速增长&#xff0c;超算算力资源正需要以任务驱动来统筹。 基于此&#xff0c;中科星图与郑州中心展开紧密合作&a…

从0开始python学习-39.requsts库

目录 HTTP协议 1. 请求 2. 响应 Requests库 1. 安装 2. 请求方式 2.1 requests.请求方式(参数) 2.2 requests.request() 2.3 requests.session().request() 2.4 三种方式之间的关联 3. 请求参数 3.1 params&#xff1a;查询字符串参数 3.2 data&#xff1a;Form表单…

React格式化规范

React并没有特定的格式要求&#xff0c;它允许开发者根据自己的喜好和项目需求来选择代码的格式化风格。然而&#xff0c;在React社区中有一些常见的约定和最佳实践&#xff0c;以下是一些常用的格式化规范和建议&#xff1a; 缩进&#xff1a;使用2个或4个空格来进行缩进&…

对‘float16_t’的引用有歧义

float16_t 是一个半精度浮点数类型&#xff0c;通常在一些需要高性能和低精度的场合被使用。 如果加了using namespace cv;后&#xff0c;OpenCV库中也有一个名为float16_t的类型定义&#xff0c;与最初的float16_t存在冲突&#xff0c;导致编译失败。 为了解决这个问题&#…

软件测试工程师需要掌握的理论知识(2)

11、如何处理WEB自动化测试中的跨域问题的? 。设置浏览器选项:在自动化测试中&#xff0c;可以通过设置浏览器选项来禁用跨域策略。这可以通过使用WebDriver的接口或设置浏览器选项的方法来实现。例如&#xff0c;对于Chrome浏览器&#xff0c;可以使用-disable-web-security参…

2024年全球网络安全预测报告

1.Gartner Gartners Top Strategic Predictions for 2024 and Beyond《Gartner顶级战略预测&#xff1a;2024年及未来》 https://www.gartner.com/en/articles/gartner-s-top-strategic-predictions-for-2024-and-beyond 2.IDC Top 10 Worldwide IT Industry 2024 Predict…

【Python可视化实战】钻石数据可视化

一、项目引言 1.背景和目标 钻石作为一种珍贵的宝石&#xff0c;其价格受到多种因素的影响。为了深入了解钻石价格的决定因素&#xff0c;我们收集了大量关于钻石的数据&#xff0c;并希望通过数据可视化来揭示钻石特征与价格之间的关系。 2.内容 收集钻石的各项特征数据&a…

2024 年初的大语言模型编程实践

首先我要明确&#xff0c;这篇文章并不旨在回顾大语言模型。显而易见&#xff0c;2023 年对人工智能来说是不平凡的一年&#xff0c;再去强调这一点似乎没有多大必要。这篇文章更多是作为一位程序员的个人体验分享。自从 ChatGPT 出现&#xff0c;再到使用本地运行的大语言模型…

【大数据】分布式协调系统 Zookeeper

分布式协调系统 Zookeeper 1.Zookeeper 的特点2.Zookeeper 的数据结构3.Zookeeper 的应用场景3.1 统一命名服务3.2 统一配置管理3.3 统一集群管理3.4 服务器动态上下线3.5 软负载均衡 Zookeeper 是 Apache 开源的一个顶级项目&#xff0c;目的是为分布式应用提供协调服务&#…

IO进程线程 day4

进程状态间的转化 创建出三个进程完成两个文件之间拷贝工作&#xff0c;子进程1拷贝前一半内容&#xff0c;子进程2拷贝后一半内容&#xff0c;父进程回收子进程的资源 #include <head.h> int main(int argc, const char *argv[]) {FILE *fp1NULL,*fp2NULL;//定义两个文…

【Java基础篇】常见的字符编码、以及它们的区别

常见的字符编码、以及它们的区别 ✔️ 解析✔️扩展知识仓✔️Unicode和UTF-8有啥关系?✔️有了UTF-8&#xff0c;为什么要出现GBK✔️为什么会出现乱码 ✔️ 解析 就像电报只能发出 ”滴” 和 ”答” 声一样&#xff0c;计算机只认识 0 和 1 两种字符&#xff0c;但是&#x…

【驱动序列】C#获取电脑硬件基本组合以及基础信息

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读《小5讲堂之知识点实践序列》文章。 这是2024年第7篇文章&#xff0c;此篇文章是C#知识点实践序列文章&#xff0c;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 要开发一款驱动小助手&…

vue封装基础input组件(添加防抖功能)

先看一下效果&#xff1a; // 调用页面 <template><div><!-- v-model&#xff1a;伪双向绑定 --><my-input v-model"inputVal" label"姓名" type"textarea" /></div> </template><script> import…

第3章 【例题】(完整版)

目录 前言 【例3.1】有关成绩结构体的例子 【例3.2】使用Score类的完整程序 【例 3.3】一个存在错误的程序 【例3.4】用对象赋值语句的例子 【例3.5】为类Score定义一个构造函数 【例3.6】建立对象的同时&#xff0c;用构造函数给数据成员赋初值 【例3.7】用成员初始…

ps -ef | grep 命令详解

ps 命令的作用是显示进程信息的&#xff1b; | 符号&#xff0c;是个管道符号&#xff0c;表示ps 和 grep 命令同时执行&#xff1b; grep 命令是查找&#xff08;Global Regular Expression Print&#xff09;&#xff0c;能使用正则表达式搜索文本&#xff0c;然后把匹配的…

Python实现pytest的参数化功能,使得可以在多组输入参数下运行同一个测试函数。

在pytest中&#xff0c;可以使用pytest.mark.parametrize装饰器来实现参数化功能。以下是一个示例代码&#xff1a; import pytest# 定义测试函数 def add(x, y):return x y# 使用pytest.mark.parametrize装饰器指定参数化的参数 pytest.mark.parametrize("x, y, expect…

VUE3-响应式

VUE3-响应式 响应式简介为什么使用Proxy图解实现流程DEMO实现讲解DEMO-reactiveDEMO-baseHandlerDEMO-EffectDEMO-Ref响应式简介 Vue 3引入了新的响应式系统。这个新的响应式系统使用了 ES6 的 Proxy 和 Reflect 的新特性,相对于 Vue 2.x 使用的 Observer 和 Watcher,提供了更…