【LINUX系统编程】多线程并发:条件变量cond和“生产者-消费者模型”

C++11线程库 (六) 条件变量 Condition variables 条件变量是一个线程同步术语,它允许多个线程相互通信。 他可以让一部分线程等待(可能超时)另一个线程可能发出的继续执行通知,条件变量与总是和互斥锁相关。————cppref对于条件变量的描述 一、为什么需要条件变量? 简单来说,条件变量可以完成一些特定场合互斥锁不能(高效)完成的工作。他是多线程编程中“等待-唤起”逻辑的基础,条件变量利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使“条件成立”。等待端需要互斥锁的原因是防止在进入等待状态(. 阅读详情

一、为什么有了互斥锁,还需要条件变量?

在前面的学习中,我用互斥锁(Mutex)解决了多线程并发抢资源的“竞态条件”问题。互斥锁确实好用,就像一把门锁,保证同一时间只有一个线程能进房间。

但是,在真实的开发场景中,互斥锁暴露出了一个致命的问题。

假设我们在写一个“生产者-消费者”模型:

· 消费者线程要去仓库拿东西。如果仓库空了,它怎么办?
· 如果没有条件变量,消费者只能疯狂地加锁、检查仓库、发现没货、解锁,然后再加锁、再检查……
· 这种行为在计算机里叫“忙等待(Busy Waiting)”。就像你一直疯狂地敲仓库的门问:“有货吗?有货吗?有货吗?”

这简直是一场灾难!因为消费者线程会疯狂地占用 CPU 时间片去循环判断,导致 CPU 白白空转,极度浪费系统性能。

这时候,条件变量(Condition Variable)就该登场了。

条件变量的本质,就像是在仓库门口装了一个“门铃”。
仓库没货的时候,消费者不用再疯狂敲门了,直接在门口搬个小板凳睡大觉(阻塞等待),把 CPU 让给别人。
等生产者把货放进去,按下门铃(调用通知函数),消费者听到铃声醒过来,再去拿货。

互斥锁保护了数据的安全,而条件变量让线程学会了“优雅地休息”。接下来,我将记录我学习条件变量的核心 API 以及踩坑的过程。

二、核心API

同样的,需要先声明条件变量

pthread_cond_t cod;

1)int pthread_cond_init(pthread_cond_t *__restrict__ __cond, const pthread_condattr_t *__restrict__ __cond_attr)  初始化条件变量

2)int pthread_cond_wait(pthread_cond_t *__restrict__ __cond, pthread_mutex_t *__restrict__ __mutex)  第二个参数是当前需要放弃的互斥锁

 wait会做三件事:

a.自动释放 mtx 互斥锁!!→ 不释放的话主线程永远拿不到锁,没法修改ready,死锁!

b. 线程阻塞休眠,让出CPU,不会空轮询浪费CPU

c. 收到signal唤醒之后,自动重新获取mtx锁,函数才返回

3)int pthread_cond_timedwait(pthread_cond_t *__restrict__ __cond, pthread_mutex_t *__restrict__ __mutex, const struct timespec *__restrict__ __abstime)  定时等待,超过指定时间自动返回,避免永久卡死

4)int pthread_cond_signal(pthread_cond_t *__cond) 唤醒至少一个等待该条件变量的线程

5)int pthread_cond_broadcast(pthread_cond_t *__cond) 唤醒所有等待这个条件变量的线程

6)int pthread_cond_destroy(pthread_cond_t *__cond) 销毁对应条件变量

三、生产者-消费者示例

从线程执行顺序可看出,等生产者把货放进去,按下门铃(调用通知函数),消费者听到铃声醒过来,再去拿货,很有序

可以加个is_over标志位,当生产者不再生产,需要通知消费者,避免永久阻塞,这点很重要

注意,修改共享变量一定要上锁!保证互斥访问

详解条件变量 条件变量是多线程编程中实现线程同步的重要工具,它允许线程在特定条件下等待,并在条件满足时被唤醒。通过与互斥锁结合使用,可以确保线程安全,避免竞态条件的发生。在实际应用中,条件变量常用于生产者-消费者模型、信号量等场景中,以实现线程间的协调与同步。 阅读详情

相关推荐

Linux多线程消费者和生产者模型实例(互斥锁和条件变量使用)

条件变量与互斥锁使用,生产者和消费者模型

Be The Best! 5369

linux多线程之条件变量

转载:https://blog.youkuaiyun.com/qq_39736982/article/details/82380689 1、条件变量概述: 条件变量是用来等待线程而不是上锁的,条件变量通常和互斥锁一起使用。条件变量之所以要和互斥锁一起使用,主要是因为互斥锁的一个明显的特点就是它只有两种状态:锁定和非锁定,而条件变量可以通过允许线程阻塞和等待另一个线程发送信号来弥补互斥锁的不足,所以互斥锁和条件...

BuZiShuoquoto的博客 1033

Linux多线程编程(三)-----生产者与消费者(条件变量,信号量)

Linux多线程编程(一):http://blog.youkuaiyun.com/llzk_/article/details/55670172 Linux多线程编程(二):http://blog.youkuaiyun.com/llzk_/article/details/55805851 在前两篇文章中我们探讨了线程的概念,同步与互斥概念以及互斥锁。本文将剖析一种操作系统中重要的模型—–生产者与消费者。其中会涉及条件变量

LLZK_的博客 4516

条件变量(condition_variable)

一、定义: 1.1、解释: 条件变量是利用线程间共享的变量进行同步的一种机制,是在多线程程序中用来实现"等待–>唤醒"逻辑常用的方法,用于维护一个条件(与是条件变量不同的概念),线程可以使用条件变量来等待某个条件为真,注意理解并不是等待条件变量为真。 当条件不满足时,线程将自己加入等待队列,同时释放持有的互斥锁; 当一个线程唤醒一个或多个等待线程时,此时条件不一定为真(虚假唤醒)。 1.2、个人理解: 两个线程利用条件变量及互斥锁实现同步。条件变量和互斥锁对两个线程来说是全局的。 一个线程利用条件变

个人工作中学到的专业技术与职业发展知识笔记 1万+

网络抓包实战:如何捕获与解析802.1Q VLAN标签报文

在网络通信中,数据包是信息传输的基本单元,而VLAN(虚拟局域网)技术通过在数据链路层插入802.1Q标签,实现了网络流量的逻辑隔离与高效管理。其核心原理是在标准以太网帧头中嵌入4字节的VLAN标识,使交换机能够根据VID(VLAN ID)进行精准转发。掌握VLAN报文的捕获与解析技术,对于网络故障排查、安全审计和性能优化具有重要价值,尤其在需要验证网络隔离策略或诊断Trunk链路异常时。本文聚焦于使用Wireshark工具,结合端口镜像等实操方法,详细演示如何抓取并解读携带802.1Q标签的原始报文,帮助

weixin_33417488的博客 381

如何在 Ubuntu 24.04 或 22.04 上安装和使用 GDebi

本文介绍了在Ubuntu 24.04上安装和使用GDebi的方法。GDebi是DPKG的轻量级替代品,能够自动解析并安装.deb包的依赖项。文章详细说明了系统更新、安装GDebi的步骤,并演示了通过GUI和CLI两种方式安装.deb包的操作流程。此外,还提供了验证安装和卸载包的方法。GDebi虽然非必需,但为用户提供了处理依赖项的另一种选择,适合需要安装本地Debian包的用户。

山岚的运维笔记 1968

C++ 多线程学习(3) ---- 条件变量

比如上面的代码中如果不加锁保护,在判断 mDisplayQueue.empty() 的条件成立后,此时线程被挂起,调度了另一个线程,另外的线程用于唤醒这个 condition_variable,此时当前线程因为还没有处于 wait 状态上(没有处于调度器的等待队列上),所以会丢失掉这个唤醒操作,如果这个唤醒操作只有一次,那么当前线程很可能永远处于阻塞等待的状态上。要解决该问题,就必须让生产者在缓冲区满时休眠,等到下次消费者消耗缓冲区中的数据的时候,生产者才能被唤醒,开始往缓冲区添加数据。

小猪佩奇的博客 9970

不用公网IP!用Ollama+Chatbox搭建家庭AI助手(内网穿透方案对比)

本文详细介绍了如何利用Ollama和Chatbox在家庭局域网中搭建本地AI助手,无需公网IP即可实现内网穿透。通过对比不同穿透方案(如Tailscale、FRP等),提供最优配置建议,帮助用户低成本部署隐私安全的家庭AI系统,适用于智能家居、儿童教育等多种场景。

weixin_26765287的博客 459

Linux:多线程---同步&&生产者消费者模型

文章摘要: 本章深入探讨线程同步机制,重点介绍了条件变量的实现原理和使用方法。通过VIP自习室的类比,阐述了条件变量如何配合互斥锁解决线程调度问题。文章分析了代码中常见的线程安全问题,如共享资源访问冲突和数据竞争。随后引入生产者消费者模型,解释其通过"超市"缓存区实现生产消费解耦的原理,并指出模型中的三类线程关系:生产者间互斥、消费者间互斥、生产消费间互斥与同步。最后通过代码示例展示了条件变量的实际应用,包括线程等待、唤醒机制以及临界资源状态判断的注意事项。

知北游天的博客 3150

Python实战:用MOOTDX库轻松抓取股票分时数据并绘制专业图表(附完整代码)

本文详细介绍了如何使用Python的MOOTDX库获取股票分时数据,并通过Pandas进行数据清洗与VWAP计算,最后利用Matplotlib绘制包含价格线、均线和成交量的专业分时图。文章提供了从环境搭建、数据获取到可视化呈现的完整代码,帮助读者快速构建本地化的股票分时数据分析工具。

weixin_29041195的博客 472

AVL(Athena Vortex Lattice)如何编写与应用(一)

前两个是弦向的涡个数和以cos函数分布的间距参数(设为1即可)后两个可以在这里声明也可以写到后面的每一个section中,是展向的涡个数和以sin函数分布的间距参数。这个文件是用来建立飞机模型的文件,是一定要有的文件,其他的.run和.mass并不是必须要有的,甚至mass文件并没有看到有人在使用。Sref、Cref、Bref是飞机的参考面积参考弦长和参考的展长,我的理解就是所设计飞机的S,c,b这三个参数。———————————————以上是飞机的基本信息———————————————

dawangaa的博客 1508

​生产者消费者问题(互斥锁和条件变量的结合)

本篇文章对生产者消费者(模型)问题进行了详解。其中给出了基于阻塞队列的生产者消费者模型demo代码和对涉及到的条件变量与互斥锁的操作也进行了详细解释。解释了条件变量等待时,为什么还需要一把锁的问题。对生产者消费者(模型)问题进行总结,且解释了生产者消费者(模型)问题效率提升的所在。希望本篇文章会对你有所帮助。

weixin_67596609的博客 2442

手把手教你用CANopen SDO报文控制步进电机(附CIA402协议详解)

本文详细解析了如何通过CANopen SDO报文控制步进电机,深入讲解CIA402协议的核心架构、状态机模型及对象字典管理,并提供实战代码示例。从SDO报文构造到多轴同步控制,帮助开发者掌握工业级步进电机的精确控制技术,适用于自动化设备开发。

weixin_33737774的博客 484

[Linux][多线程][三][条件变量][生产者消费者模型][基于BlockingQueue的生产者消费者模型]详细讲解

[Linux][多线程][三][条件变量][生产者消费者模型][基于BlockingQueue的生产者消费者模型]详细讲解

SnowK博客 5385

信创服务器(麒麟 V10 SP3)安装 NVIDIA GeForce RTX 5070 驱动

本文介绍了在麒麟V10 SP3系统上安装NVIDIA RTX 5070显卡驱动的详细步骤。首先需要关闭nouveau驱动,安装必要的编译环境和工具,确保内核版本与kernel-devel完全一致。最后运行NVIDIA驱动安装程序,关键选择包括启用DKMS支持、编译模块、禁用32位兼容和nouveau驱动。整个流程适用于海光CPU和Blackwell架构GPU的国产操作系统环境。

猿小白的博客 668

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

【Linux操作系统】Linux系统编程中条件变量实现生产者消费者模型

在Linux系统编程中,条件变量是一种用于线程间同步的机制,常用于实现生产者消费者模型。生产者消费者模型是一种常见的并发编程模型,用于解决多线程环境下的数据共享和同步问题。在该模型中,生产者负责生产数据,消费者负责消费数据,而条件变量则用于在生产者和消费者之间进行同步。

Goforyouqp的博客 4073

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【Linux】线程同步 条件变量精讲 + 生产者消费者模型完整实现

互斥锁易引发线程饥饿与 CPU 效率低下问题,本文基于 Linux pthread 库讲解条件变量的核心原理与接口使用,阐述线程同步的本质;结合经典生产者消费者模型,实现阻塞队列的基础版本,并通过 RAII 思想完成条件变量与互斥锁的封装,推出更安全优雅的阻塞队列 V2 版,同时演示任务对象与函数的传递场景。

2501_90265152的博客 1092

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【Linux系统编程】多线程编程:cond(条件变量)实现生产者消费者模型

线程同步典型的案例即为生产者消费者模型,而借助条件变量来实现这一模型,是比较常见的一种方法。假定有两个线程,一个模拟生产者行为,一个模拟消费者行为。两个线程同时操作一个共享资源(一般称之为汇聚),生产者向其中添加产品,消费者从中消费掉产品。相较于互斥量而言,条件变量可以减少竞争。如直接使用互斥量,除了生产者、消费者之间要竞争互斥量以外,消费者之间也需要竞争互斥量,但如果汇聚(链表)中没有数据,消费者之间竞争互斥量是无意义的。有了条件变量机制以后,只有生产者完成生产,才会引起消费者之间的竞争。

Stark的博客 1391

linux条件变量pthread_cond_wait和pthread_cond_signal函数

3、当被唤醒,pthread_cond_wait函数返回时,解除阻塞并重新申请获取互斥锁pthread_mutex_lock(&mutex);本次分析linux中的条件变量,条件变量本身不是锁,但它也可以造成线程阻塞,通常与互斥锁配合使用,给多线程提供一个会合的场所。1.4.pthread_cond_timedwait函数。

weixin_42936764的博客 2418

《Linux系统编程》Linux 系统多线程(五):<线程同步与互斥>线程同步(上):从条件变量到生产者消费者模型详解

本文深入探讨了Linux线程同步的核心概念与实现方法。首先分析了互斥锁的局限性,指出仅靠互斥无法解决线程饥饿和资源浪费问题。随后重点讲解了条件变量的原理与使用规范,包括其原子性操作特性及避免伪唤醒的while循环判断模式。文章通过生产者消费者模型这一经典案例,详细展示了如何利用双条件变量实现高效线程同步,并提供了单生产单消费、多生产多消费等多种场景的代码实现。最后强调生产者消费者模型的三大优势:解耦、支持忙闲不均和提高并发效率,为开发高并发程序提供了重要范式。

2501_91275995的博客 340

Linux多线程之条件变量(生产者和消费者模型)

条件变量 【条件变量本身不是锁!但是它也可以造成线程阻塞。通常与互斥锁配合使用。给多进程提供一个会和的场所(共享数据)】 主要应用函数 1. pthread_cond_init //初始化条件变量 2. pthread_cond_destroy //销毁条件变量 3. pthread_cond_wait //线程等待信号触发,如果没有信号触发,无限期等待下去。 4. pthread_cond_timedwait //线程等待一定的时间,如果超时或有信号触发,线程唤醒。 5. pthread_con

qq_41033011的博客 1888

Linux的多线程——生产者与消费者(条件变量、信号量)

生产者与消费者模型的简单介绍、条件变量和信号量的理解

rushing的博客 6667

【Linux】生产者-消费者模型及条件变量

摘要:生产者-消费者模型通过互斥锁和条件变量解决多线程同步问题。该模型维护三种互斥关系(生产者间、消费者间、生产者与消费者间),两种角色(生产者、消费者)和一个共享数据空间。条件变量使线程在条件不满足时阻塞等待,避免无效轮询。代码实现时需注意"伪唤醒"问题,应将if判断改为while循环确保安全。文中展示了基于队列的封装实现,包含任务分发功能,通过互斥锁保证线程安全,条件变量实现高效通知机制,最终构建出稳定的生产者-消费者系统。

lsir10110_的博客 792

【Linux】条件变量及生产者消费者模型

条件变量与生产消费者模型

2301_78636079的博客 1468

Linux:线程同步之条件变量(条件变量的概念、作用、使用方法、手写实现生产者-消费者模型)

Linux:线程同步之条件变量(条件变量的概念、作用、使用方法、手写实现生产者-消费者模型);1.条件变量的相关函数:pthread_cond_init、pthread_cond_siginal、 pthread_cond_broadcast、pthread_cond_wait、pthread_cond_timewait等使用;2.生产者消费者模型的实现(使用条件变量和互斥锁实现该模型)

qq_42279379的博客 1307
上一篇: 【Linux系统编程】多线程并发:读写锁(rwlock)
下一篇: 【Linux系统编程】多线程并发:POSIX 信号量(无名&有名)+信号量版生产者-消费者
better on Saturn
博客等级 码龄12天 1粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值