C++11 多线程同步 互斥锁 条件变量

C++同步机制之条件变量(std::condition_variable) 文章目录一、使用机制1.1 涉及的主要概念1.2 wait线程中的用法1.3 notify线程中的用法二、成员函数2.1 唤醒函数2.2 等待函数三、为什么需要互斥锁四、虚假唤醒五、示例 对多线程编程有了解的对条件变量(condition_variable)这个概念一定不陌生,相较于另一种常见的同步机制互斥锁,条件变量是一种更高层次的同步手段,互斥锁用于保护一段临界区,也就是各个线程互斥地去访问同一块资源,这是一种很简单直接的同步手段,可以cover住很大一类的同步场景,比如多线程修改一个非线程安全的uno 阅读详情

C++11 多线程同步 互斥锁 条件变量

 

本文链接:https://blog.youkuaiyun.com/yangbodong22011/article/details/60348742

在多线程程序中,线程同步(多个线程访问一个资源保证顺序)是一个非常重要的问题,Linux下常见的线程同步的方法有下面几种:

  • 互斥锁
  • 条件变量
  • 信号量

这篇博客只介绍互斥量和条件变量的使用。

互斥锁和条件变量

通常情况下,互斥锁和条件变量是配合使用的,互斥锁用于短期锁定,主要保证线程对临界区的进入;条件变量用于线程长期等待,在wait的时候会释放锁。操作的API如下所示(介绍最常用的):

std::mutex : 独占的互斥量,不能递归使用
std::condition_variable :条件变量,配合 std::unique<std::mutex>进行wait操作。
std::condition_variable_any 和任意带有lock,unlock的mutex配合使用,但是效率比std::condition_variable差。

举个栗子:

10个人排队使用打印机,任一时刻只有一个人能使用。用一个变量i的0和1两种状态分别表示打印机能不能使用。这个程序这样写,详细解释见注释:

#include<iostream>
#include<condition_variable>
#include<vector>
#include<thread>

std::vector<std::thread> tv;         //保存线程的情况
std::condition_variable_any m_t;     //条件变量
std::mutex lock;                     //互斥锁
int i = 1;                           //打印机资源 初始为1 表示可用


void subi() {            
    std::lock_guard<std::mutex> locker(lock);  //使用之前先加锁
    while(i == 0){             //如果不可用                
        m_t.wait(lock);        //将当前线程阻塞,注意:此时会释放锁
    }

    i--;                       //使用打印机过程
}

void addi() {                 
    std::lock_guard<std::mutex> locker(lock); //同理,放弃使用的时候先加锁

    i++;                       //是资源变为可用
    m_t.notify_all();          //通知其余阻塞的使用者可以使用了
}

void func(int j) {
    subi();
    std::cout << "I am thread "<< j << " , i = " << i << std::endl;
    addi();
}


int main(int argc,char *argv[])
{
    for(int j = 0; j < 10 ; ++j) {
        std::thread t(func,j);
        tv.push_back(std::move(t));
    }

    for(auto &thread : tv) {
        thread.join();
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

测试情况应该是:每个进程输出的i都为0,表示每个进程都在合理的使用打印机,没有出现同时使用的情况,即i < 0的情况。

$ g++ condition.cpp -pthread //注意链接pthread

这里写图片描述

嗯,可见我们的使用姿势是正确的~

华为无线WiFi实战:基于802.1x与NPS的企业级认证部署指南 本文提供了一份详尽的华为无线WiFi企业级认证部署实战指南。通过整合802.1x协议与Windows NPS服务器,构建基于AD域账号的安全认证体系,彻底解决传统WiFi密码共享带来的安全风险。文章详细拆解了从NPS服务器配置、证书部署到华为AC端RADIUS模板、AAA方案、认证域及VAP模板调用的全流程,并附有终端连接测试与常见故障排查方法,助力企业实现高效、安全的无线网络接入管理。 阅读详情

相关推荐

MQTT阿里云OTA 调试记录

2.验证,这个验证是什么意思呢,就是阿里云会把你包的信息,比如包大小,streamid(相当于包的识别码),版本号发送给你的设备,然后如果你没发送升级成功的包给阿里云,这里会是一直验证中的状态,那你的设备每次重新连接阿里云,发送connect包给阿里云的时候,阿里云就会发送一次这个验证(upgrade)包。提取到了之后就可以发送请求包了,这个请求包比较坑,也可能是我没付费,他的包一次最多只有1024个字节的数据。之前说了,验证状态下,设备发送connect包给阿里云,阿里云就会发一个upgrade包给你。

qq_42585211的博客 1231

C++同步锁管理的一种方法

在C++中,通过提供构造函数、析构函数来对处理资源的获取、释放。 通过C++的这种机制,我们可以很方便地处理C++中的加锁同步机制。把锁对象作为Guard对象的一个成员(m_lock),然后在Guard对象的构造中对m_lock进行加锁:m_lock.acquire(),在Guard对象的析构函数中进行解锁:m_lock.release()。先给出代码实例如下:template class Guard{public :        Guard(const T & lock);        virtual

Kevin_Shaw的专栏 2602

无限维李代数局部与2-局部1/2-导子:从概念到Witt代数实例解析

在抽象代数与数学物理中,李代数是描述对称性的基本结构,而导子则是刻画其微分性质的核心算子。从经典的导子概念出发,通过引入“局部”与“分数阶”两个关键推广,形成了局部导子、2-局部导子以及1/2-导子等重要研究方向。这些推广不仅深化了对无限维李代数(如Witt代数、Virasoro代数)复杂结构的理解,其研究方法和结论也为共形场论、可积系统等物理理论提供了数学基础。本文聚焦于无限维李代数上局部与2-局部1/2-导子的系统研究,通过拆解核心概念、剖析典型代数结构,并以Witt代数为实例,详细演示了从全局1/2-

weixin_34072296的博客 392

C++之线程同步、死锁问题

C++之线程同步、死锁问题

weixin_65743593的博客 1113

uniapp运行钉钉小程序

因项目原因,公司需要在钉钉里面开发小程序。之前用uniapp开发过app,H5,小程序。还真没尝试过钉钉小程序,今天就简单的记录下uniapp运行钉钉小程序中的过程。

YL 2919

maxwell 平面变压器仿真(一)

在学习开关电源设计的时候,我们难免要设计变压器,采用有限元仿真软件MAXWELL 可以帮助我们确定变压器的励磁电感,漏感等参数。对于我们的理论分析大有裨益。但是苦于这破软件的教程真的是相当的零散,我相信大家用起来也总是苦于没有系统的教程指导,撰写本文的目的有两个,一个是记录自己使用的一些问题,一个是给大家提供一个可以参考的文档。

qq_45405656的博客 8247

C++新特性31_利用C++自己封装线程同步锁(利用类的构造析构实现加锁解锁的自动化、利用引用实现在一个类中对另一个类的唯一对象的调用方法、利用对象及局部变量作用域减小颗粒度、其他类对象成员函数调用)

上两篇C++新特性29_线程同步问题的解决思路(原子操作、WindowsAPI实现原子操作、针对特定操作的WindowsAPI、如何解决同步的一般问题、 实际场景介绍解决同步问题的思路、)及C++新特性30_windows api解决线程同步(临界区、手动加EnterCriticalSection(&),LeaveCriticalSection(&)、临界区大小即颗粒度、如何自动加锁)中介绍了Windows API解决同步问题的两种方法,一种是针对特定操作的API,另一种是使用临界区的形式实

分享学习成长历程,Winter is coming! 1329

避坑指南:LVGL在Arduino环境编译报错?3步搞定lv_conf.h路径问题(附ST7789屏幕调试技巧)

本文详细解析了在Arduino环境中配置LVGL图形库时,如何解决常见的“lv_conf.h file not found”编译报错问题。通过三步法:定位并复制模板文件、启用核心配置并指定路径、配置基础参数,从根本上解决路径问题。文章还结合ST7789屏幕驱动,分享了使用TFT_eSPI库进行显示适配、内存优化及背光控制等实战调试技巧,帮助开发者建立清晰、可维护的嵌入式UI工程基础。

lake5的博客 860

C++ 线程同步之互斥锁

进行多线程编程,如果多个线程需要对同一块内存进行操作,比如:同时读、同时写、同时读写,对于后两种情况来说,如果不做任何的人为干涉就会出现各种各样的错误数据。解决多线程数据混乱的方案就是进行线程同步,最常用的就是互斥锁,在 C++11 中一共提供了四种互斥锁:不论是在 C 还是 C++ 中,进行线程同步的处理流程基本上是一致的,C++ 的 mutex 类提供了相关的 API 函数:成员函数 独占互斥锁对象有两种状态:锁定和未锁定。 除了使用 lock() 还可以使用 try_lock() 获取互斥锁

喜欢打篮球的普通人 6623

[Dify] 如何在Dify中解析上传的TXT文件内容

在Dify平台上构建智能应用时,解析用户上传的.txt文件是关键步骤。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 2637

C 语言多文件编程 : 大型程序的组织与管理

本文介绍了C语言多文件编程的核心概念与实践方法。主要内容包括:1. 多文件编程的必要性:解决单文件编程在大型项目中的维护和协作问题;2. 文件组织方式:头文件(.h)负责声明接口,源文件(.c)实现具体功能;3. 编译链接过程:分阶段编译和链接多个源文件;4. 头文件设计原则:包含接口声明、使用保护机制、保持自包含性;5. 模块化实践:通过示例展示学生信息管理系统的模块划分;6. 构建工具:介绍Makefile的编写和使用方法。文章还提供了创建静态库和动态库的指导,并强调了模块化设计、信息隐藏等软件工程原则

2503_91057718的博客 1947

C++多线程同步的5种方式:互斥锁mutex、条件变量condition_variable、信号量sempahore、异步操作future、原子操作atomic

C++多线程同步的5种方式讲解:互斥锁mutex、条件变量condition_variable、信号量sempahore、异步操作future、原子操作atomic。

欧特GO 2260

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

C++11中的多线程同步:互斥锁、信号量、条件变量、异步操作、原子操作

互斥锁 互斥锁保证某一时刻,只能在一处获取锁,当当前线程拥有锁时,其他线程如果想获取锁,那么必须等待直到对方解锁。C++11中的互斥锁:std::mutex, std::lock_guard, std::unique_lock。 std::mutex C++11中定义的互斥量,实现互斥锁的功能,即同一时刻只能有一个线程获取该锁。底层的实现原理是包装了pthread_mutex_t结构体,并调用pthread_mutex_lock和pthread_mutex_unlock完成加锁和解锁的功能。其内存布局: t

mingyuan_liu的博客 6894

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C++11多线程同步:从互斥锁到条件变量的核心原理与实战

多线程编程是现代软件开发中提升程序性能的关键技术,其核心挑战在于如何协调多个并发执行的线程,确保数据访问的安全性与一致性。这涉及到对共享资源的有序访问控制,以避免数据竞争和竞态条件等常见问题。从技术原理层面,线程同步机制通过提供互斥访问、条件等待等原语,为并发程序的可预测性和正确性奠定基础。其技术价值在于能够充分利用多核处理器资源,构建高性能、高响应的服务器、游戏引擎及实时系统。在实际应用场景中,生产者-消费者模式、线程池、读写锁等经典设计模式都深度依赖高效的同步机制。本文聚焦于C++11标准库提供的同步工

weixin_42568801的博客 238

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C++11多线程同步实战:互斥锁、条件变量与原子操作详解

并发编程是现代软件开发的核心概念,旨在通过多线程执行提升程序性能与响应能力。其核心原理在于协调多个线程对共享资源的访问,避免数据竞争与执行顺序冲突,从而确保线程安全。在C++11标准中,这一技术价值通过引入标准线程库得以实现,为开发者提供了跨平台的高效并发工具。具体应用场景包括高性能服务器开发、图形界面响应优化以及并行计算任务处理。本文聚焦于C++11中的关键同步机制,深入探讨互斥锁如何作为共享资源的守门员防止数据竞争,以及条件变量如何实现线程间的等待与通知机制,并结合原子操作展示无锁编程的高效实践。

weixin_29231725的博客 228

C++11条件变量使用详解

condition_variable介绍 在C++11中,我们可以使用条件变量(condition_variable)实现多个线程间的同步操作;当条件不满足时,相关线程被一直阻塞,直到某种条件出现,这些线程才会被唤醒。 其主要成员函数如下: 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作: 一个线程因等待"条件变量的条件成立"而挂起; 另外一个线程使"条件成立",给出信...

Keep Moving~ 4万+

C++11多线程同步原语深度解析:互斥锁、条件变量与原子操作实战

多线程同步是并发编程的核心概念,旨在协调多个线程对共享资源的访问顺序,防止数据竞争和状态不一致。其基本原理是通过特定的同步机制,如互斥锁和条件变量,来建立线程间的执行顺序约束。从技术价值看,有效的同步能保障程序的正确性、提升资源利用率和系统吞吐量。在应用场景上,无论是构建高性能服务器、实现并行计算,还是开发响应式桌面应用,都离不开对同步原语的恰当运用。本文聚焦于C++11标准库提供的核心同步工具,深入剖析互斥锁如何作为共享资源的‘独木桥’实现独占访问,并详解条件变量如何扮演线程间的‘信号灯’,通过等待与通知

weixin_29199873的博客 312

C++11多线程同步实战:互斥锁、条件变量、原子操作与异步编程详解

并发编程是现代软件开发的核心技术,旨在通过多线程或多进程提升程序性能与响应能力。其核心原理在于协调多个执行单元对共享资源的访问,以避免数据竞争与执行顺序混乱。从技术价值看,有效的同步机制能确保程序正确性、提升资源利用率并实现复杂协作逻辑。典型应用场景包括高性能服务器、实时数据处理、GUI应用及分布式系统。本文聚焦C++11标准库,深入剖析互斥锁、条件变量、原子操作等关键同步原语,通过生产者-消费者模型等实例,详解如何避免死锁、处理虚假唤醒及选择合适工具,为构建健壮高效的并发程序提供实践指导。

weixin_42531886的博客 244

C++11 多线程的使用及线程同步

C++线程操作 C++11 中提供的线程类 std::thread ,基于此类创建一个新的线程相对简单,只需要提供线程函数和线程对象即可; 文章目录C++线程操作1.命名空间 this_thread1.1 get_id()1.2 sleep_for()1.3 sleep_until1.4 yield()2. C++ 线程类2.1构造函数2.2 公共成员函数2.2.1 get_id() 函数2.2.2 join() 函数2.2.3 detach() 函数2.2.4 joinable() 函数2.3 静态

weixin_49730048的博客 2777

C++11线程间同步方式

1.多线程的并发问题 线程间为什么需要同步?直接来看一个例子: int a = 0; void foo() { for (int i = 0; i < 10000000; ++i) { a += 1; } } int main() { clock_t start, end; start = clock(); thread t1(foo); thread t2(foo); ...

东东儿的博客 4128

一文看懂C++11的互斥锁、条件变量、原子变量

本文介绍了C++11多线程编程中的同步机制,主要包括互斥锁、条件变量和原子操作。在多线程环境中,由于CPU时间片切换、缓存不一致等问题,对共享变量的访问会造成数据竞争。C++11提供了std::mutex等多种互斥锁类型,以及std::lock_guard等RAII风格的锁管理类来避免死锁。条件变量(std::condition_variable)用于线程间高效同步,典型应用于生产者-消费者模型。原子操作(std::atomic)则通过硬件支持实现无锁编程,提供load、store等原子函数及6种内存顺序控

m0_62504616的博客 1309

c++11标准(6)——并发库(条件变量)

欢迎来到博主的专栏:c++杂谈博主ID:代码小豪。

2301_77239666的博客 954

C++ 多线程基础及 C++11 多线程库总结

1. 多线程基础 1.1 进程与线程 根本区别: 进程是操作系统资源分配的基本单位,线程是任务调度和执行的基本单位 开销方面: 每个进程都有自己独立的代码和数据空间,程序之间的切换开销较大。 线程可以看作是轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换开销小。 所处环境: 一个操作系统能同时运行多个进程(程序)。 在一个进程中,可以有多个线程同时执行。 内存分配方面: 系统在运行的时候会为每个进程分配不同的内存空间。 对线程而言,系统不会为

生命在于折腾! 4003

突破编程_C++_C++11新特性(多线程编程的基础知识)

C++11 新特性:多线程编程的基础知识

突破编程 931
上一篇: char* 和 char[] 的区别
下一篇: Java学习笔记:GUI基础。
TuxedoLinux
博客等级 码龄9年 268粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值