当前位置: 首页 > news >正文

C++ 多线程(互斥锁、条件变量)

互斥锁
最简单示例:

#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;
int counter = 0;void increment() {for (int i = 0; i < 10000; ++i) {// b1 是创建出来的对象.  lock_guard 类似智能指针一样,为了防止忘记释放锁// 锁的管理范围看作用域范围 {}std::lock_guard<std::mutex> b1(mtx);counter++;}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Counter value: " << counter << std::endl;return 0;
}

条件变量+互斥锁
互斥锁:保证只要一个线程在修改变量
条件变量:线程1与线程2之间需要一个同步信号,来统一控制线程是否该运行或者等待

#include <iostream>
#include <string>
#include <thread>  // 多线程
#include <vector>
#include <mutex>  // 互斥锁
#include <condition_variable>  // 条件变量
#include <chrono>  // 处理时间库//using namespace std;std::mutex mtx1;              // 互斥锁对象   
std::condition_variable cv_1; // 条件变量对象bool state = false;          // 条件变量 变量// 不使用传递引用
//void read_camera(std::string rtsp, std::string window_name) {// 使用传递引用避免拷贝
void read_camera(const std::string& rtsp, const std::string& window_name) {// 互斥锁 使用std::unique_lock<std::mutex> lck(mtx1);while (!state) {cv_1.wait(lck);  // 条件不成立 进入阻塞状态 释放掉锁 等待别人唤醒}for (int i = 0; i < 9999; i++) {std::cout << i << std::endl;}std::cout << "后启动的线程id:" << std::this_thread::get_id() << std::endl;std::cout << "rtsp" << rtsp << std::endl;std::cout << "window_name    " << window_name << std::endl;std::this_thread::sleep_for(std::chrono::seconds(2));  // 休眠2秒}void read_camera_1() {std::cout << "线程id:" << std::this_thread::get_id() << std::endl;std::this_thread::sleep_for(std::chrono::seconds(2));  // 休眠2秒// 互斥锁 使用std::unique_lock<std::mutex> lck(mtx1);state = true;cv_1.notify_all();  // 通知所有线程
}int main()
{ 单个线程启动//std::string param1 = "./jian_qian.mp4";//std::string param2 = "1";//std::thread t1([param1, param2]() {//    read_camera(param1, param2);//    });// 测试互斥锁 休眠2秒std::thread t([ ]() {read_camera_1();});// 循环启动线程// 要保证容器内的数量一致std::vector <std::string> camera_path{ "./jian_qian.mp4", "./jian_qian.mp4" };std::vector <std::string> camera_name{ "1", "2" };// 这里我用循环启动了2个线程,实际执行时,先会执行休眠2秒的函数,然后这两个线程会抢占运行先后顺序,// 假如第一个抢到了,第二个要等第一个运行完毕后才能运行,因为代码中互斥锁+条件变量 是只有一个线程可以运行,其他需要等待。std::vector<std::thread> threads;for (int i = 0; i < camera_path.size(); i++) {// 不传递引用//threads.push_back(std::thread([camera_path_i = camera_path[i], camera_name_i = camera_name[i]]() {//    read_camera(camera_path_i, camera_name_i);//    }));// 使用 std::ref 传递引用,避免值拷贝threads.push_back(std::thread(read_camera, std::ref(camera_path[i]), std::ref(camera_name[i])));}t.join();// 阻塞等待所有线程完成for (auto& t : threads) {// 避免重复启动线程,防止线程意外,未正确释放资源if (t.joinable()) {t.join();}}return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • SQL server 2008 获取当前年,季度 和月的最后一天
  • 游戏开发设计模式之装饰模式
  • Java新版主要特性|2024年最后一个版本即将到来
  • DataWhale AI夏令营 2024大运河杯-数据开发应用创新赛-task2
  • 源代码防泄露迎来信创时代:信创沙箱
  • 数据分析之Python对数据分组排序
  • TESSY创建单元测试或集成测试工程
  • 基于NNG的六种通信模式
  • 【运维类】信息化项目运维方案(word)
  • day44——C++对C的扩充
  • Spring(面试篇)
  • Linux:SQLite 数据库
  • #QT 笔记一
  • Linux实操笔记1 向服务器出发:连接和登录
  • 大模型LLM的Token相关问题:模型不同,token计算不同,gpt对token的计算,我们如何选择token及token评估模型
  • [case10]使用RSQL实现端到端的动态查询
  • [LeetCode] Wiggle Sort
  • 08.Android之View事件问题
  • Android系统模拟器绘制实现概述
  • C++类中的特殊成员函数
  • GitUp, 你不可错过的秀外慧中的git工具
  • Java方法详解
  • Vue.js源码(2):初探List Rendering
  • 动态魔术使用DBMS_SQL
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 京东美团研发面经
  • 聚类分析——Kmeans
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 你真的知道 == 和 equals 的区别吗?
  • 悄悄地说一个bug
  • 一个JAVA程序员成长之路分享
  • 如何在招聘中考核.NET架构师
  • 数据库巡检项
  • # Apache SeaTunnel 究竟是什么?
  • # Redis 入门到精通(一)数据类型(4)
  • # 飞书APP集成平台-数字化落地
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (39)STM32——FLASH闪存
  • (bean配置类的注解开发)学习Spring的第十三天
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (篇九)MySQL常用内置函数
  • (十)c52学习之旅-定时器实验
  • (四)React组件、useState、组件样式
  • (贪心 + 双指针) LeetCode 455. 分发饼干
  • (一)UDP基本编程步骤
  • (转)母版页和相对路径
  • (转载)CentOS查看系统信息|CentOS查看命令
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • .bashrc在哪里,alias妙用
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉