彻底搞懂 C++ 锁、条件变量和生产者-消费者模式

发布时间:2026/7/9 3:19:54
彻底搞懂 C++ 锁、条件变量和生产者-消费者模式 文章目录彻底搞懂 C 锁、条件变量和生产者-消费者模式一、锁mutex到底是什么二、两种锁的区别三、条件变量condition_variable不用条件变量——轮询浪费 CPU用条件变量——数据没到就睡到了自动醒wait 到底做了什么notify_one 和 notify_all为什么 wait 需要一个条件 lambda四、生产者-消费者模式最简单版本为什么两个消费者交替取数据关键细节五、我项目里的 BlockingQueue六、常见面试问题速答Q: lock_guard 和 unique_lock 的区别Q: 条件变量为什么必须配合 while 或 lambdaQ: 为什么 notify 放在 unlock 后面Q: 为什么 push 加锁了pop 的 wait 还能解锁七、我记住的关键规则彻底搞懂 C 锁、条件变量和生产者-消费者模式一、锁mutex到底是什么锁不是代码层面的东西是约定。你和室友住一间房门上挂一把锁——谁进去谁锁门出来再开。另一个人想进去门口等着。#includemutexstd::mutex mtx;// 一把锁void写日志(conststd::stringmsg){mtx.lock();// 锁门// 往文件里写日志这个操作不能同时被两个线程做mtx.unlock();// 开门}如果两个线程同时往同一个文件写日志内容会交叠错乱。加锁后同一时刻只有一个线程在写。但手动lock()/unlock()容易出事——写日志写到一半抛异常了unlock()没执行锁永远开不了所有人卡死。所以 C 提供了管家void写日志(conststd::stringmsg){std::lock_guardstd::mutexlock(mtx);// 构造 立刻加锁// 写日志...}// lock 析构 自动解锁就算中间抛异常也一定解锁lock_guard 构造加锁离开花括号自动解锁。永远用它不要手动调 lock/unlock。二、两种锁的区别lock_guardunique_lock加锁时机构造时自动构造时自动解锁时机离开{}自动离开{}自动也可以手动unlock()能临时解锁再重新加锁吗❌✅能配合条件变量吗❌✅用在哪简单临界区条件变量 / 需要灵活控制的场景// lock_guard省心绝大多数场景用它{std::lock_guardstd::mutexlock(mtx);// 操作共享数据}// unique_lock灵活条件变量必须用它{std::unique_lockstd::mutexlock(mtx);// 操作共享数据lock.unlock();// 提前解锁lock_guard 做不到// 可以做其他不涉及共享数据的操作lock.lock();// 重新加锁}三、条件变量condition_variable锁解决了同时只能一个人访问的问题但解决不了数据还没到先睡会儿的问题。不用条件变量——轮询浪费 CPUwhile(queue_.empty()){std::this_thread::sleep_for(std::chrono::milliseconds(10));// 每隔 10ms 检查一次CPU 空转反应慢}autotaskqueue_.front();queue_.pop();用条件变量——数据没到就睡到了自动醒std::unique_lockstd::mutexlock(mtx);cv.wait(lock,[]{return!queue_.empty();});// 空了就睡0% CPUautotaskqueue_.front();queue_.pop();wait 到底做了什么cv.wait(lock,[]{return!queue_.empty();});① 检查条件 !queue_.empty() → ② true → 直接返回什么都不发生 ③ false → 解锁 lock → 线程挂起睡觉0% CPU ④ 另一个线程调 cv.notify_one() 叫醒我 ⑤ 重新拿锁 → 再检查条件 → true 就取数据关键睡觉前解锁醒了重新拿锁。如果睡觉时还抱着锁不放别人怎么往队列里放东西这就是死锁。notify_one 和 notify_allcv.notify_one();// 叫醒一个正在 wait 的线程cv.notify_all();// 叫醒所有正在 wait 的线程为什么 wait 需要一个条件 lambda因为虚假唤醒——操作系统偶尔会莫名其妙叫醒线程极少见但标准允许。还有一个原因是你通知了一个线程但这期间另一个线程可能先醒、先把数据取走了。所以醒过来第一件事必须是检查条件不满足条件继续睡。四、生产者-消费者模式这是多线程编程里最常见的模式。一个或多个线程生产数据放到队列里一个或多个线程从队列里取数据处理。最简单版本#includecondition_variable#includeiostream#includemutex#includequeue#includethread#includechronostd::mutex mtx;std::condition_variable cv;std::queueintq;boolrunningtrue;voidconsumer(intid){while(running||!q.empty()){std::unique_lockstd::mutexlock(mtx);// 队列空且还在生产 → 睡觉等cv.wait(lock,[]{return!q.empty()||!running;});// runningfalse 且队列空 → 退出if(!runningq.empty())break;intvalq.front();q.pop();lock.unlock();// 数据到手就解锁不拖std::cout消费者id 取走: valstd::endl;std::this_thread::sleep_for(std::chrono::milliseconds(200));}}voidproducer(){for(inti1;i10;i){{std::lock_guardstd::mutexlock(mtx);q.push(i);std::cout生产者 放入: istd::endl;}// 离开 {} 自动解锁cv.notify_one();// 叫醒一个消费者std::this_thread::sleep_for(std::chrono::milliseconds(100));}runningfalse;cv.notify_all();// 叫醒所有人下班了别睡了}intmain(){std::threadc1(consumer,1);std::threadc2(consumer,2);std::threadp(producer);c1.join();// 等线程结束c2.join();p.join();std::cout全部结束std::endl;return0;}运行结果大概是生产者 放入: 1 消费者 1 取走: 1 生产者 放入: 2 消费者 2 取走: 2 生产者 放入: 3 消费者 1 取走: 3 ... 全部结束为什么两个消费者交替取数据因为sleep_for(200ms)让取完数据的消费者暂时不继续抢锁另一个消费者有时间拿到锁。去掉 sleep 就是纯抢锁谁抢到谁拿就不一定交替了。关键细节{std::lock_guardstd::mutexlock(mtx);q.push(i);}// ← 先解锁cv.notify_one();// ← 再通知不要抱着锁通知为什么解锁后才通知如果先通知再解锁——被叫醒的线程立刻尝试拿锁但锁还没解又得等。多此一举。解锁后通知人家醒了直接能拿到锁。五、我项目里的 BlockingQueue项目里把这些东西封装成了一个类templatetypenameTclassBlockingQueue{public:voidpush(T item){{std::lock_guardstd::mutexlock(mutex_);queue_.push(std::move(item));}cv_.notify_one();// 解锁后通知}Tpop(){std::unique_lockstd::mutexlock(mutex_);// 用 unique_lockcv_.wait(lock,[]{return!queue_.empty();});// 空了就睡T itemstd::move(queue_.front());queue_.pop();returnitem;}private:std::mutex mutex_;std::condition_variable cv_;std::queueTqueue_;};用法简单// 生产者odud 的 IPC 接收线程tx_queue_.push(OduSerialTask{...});// 消费者odud 的串口发送线程OduSerialTask tasktx_queue_.pop();// 空了自动睡不占 CPU六、常见面试问题速答Q: lock_guard 和 unique_lock 的区别A: lock_guard 只有构造加锁 析构解锁不能手动控制。unique_lock 可以临时 unlock 再 lock条件变量的 wait 必须用 unique_lock。大部分场景用 lock_guard 就够了。Q: 条件变量为什么必须配合 while 或 lambdaA: 因为虚假唤醒。线程可能被操作系统莫名其妙叫醒也可能被 notify 但数据被另一个线程抢了。醒过来必须重新检查条件不满足继续睡。Q: 为什么 notify 放在 unlock 后面A: 先 unlock 再 notify——被叫醒的线程直接能拿到锁不用再等。反过来先 notify 再 unlock被叫醒的线程发现锁还没解又要等浪费一次上下文切换。Q: 为什么 push 加锁了pop 的 wait 还能解锁A: wait 内部做的事是临时解锁 → 挂起 → 被叫醒 → 重新加锁。push 在 wait 解锁期间可以拿到锁、放数据。这正是条件变量的核心机制。七、我记住的关键规则任何共享数据被多线程读写 → 加锁。用lock_guard别手写 lock/unlock。加锁后不做耗时操作。拿数据就解锁别抱着锁做 IO。生产者-消费者 队列 锁 条件变量。生产者 push notify消费者 pop wait。wait 必须传条件判断。要么 lambda要么 while 套 wait。防止虚假唤醒。先解锁再 notify。不抱着锁通知别人。

相关新闻

别再被忽悠了!找网站建设酷万网络前,这3个坑你必须知道

别再被忽悠了!找网站建设酷万网络前,这3个坑你必须知道

网站上线三个月,访客还是两位数,钱打水漂连个响儿都听不见。这种焦虑,我懂。很多老板花大几万做个网站,结果打开一看,加载慢得像蜗牛,手机上看字小得眯着眼,百度搜都搜不到。不是技术不行,是思路错了。记得去年有个做建材的朋友,找我吐槽。他说之前找的那家,报价便宜…

发布时间:2026/7/9 3:19:23
别被忽悠了!揭秘盛世阳光网站建设背后的真相与坑

别被忽悠了!揭秘盛世阳光网站建设背后的真相与坑

说实话,做网站这行水太深了。深到你根本想象不到。很多老板花了几万块,最后拿到一个连手机都打不开的网页。真的气人。今天我就把话撂这儿,关于盛世阳光网站建设,咱们得聊聊真东西。别再听那些销售吹什么“全网最低价”。低价没好货,这是铁律。我见过太多案例,前期报价三…

发布时间:2026/7/9 3:18:25
建设工程图审管理信息系统网站怎么选?避坑指南与真实使用体验

建设工程图审管理信息系统网站怎么选?避坑指南与真实使用体验

建设工程图审管理信息系统网站怎么选?别被花哨的功能迷了眼。核心就看三点:流程顺不顺、资料安不安全、响应快不快。这篇不整虚的,直接说大实话。以前做项目的时候,最头疼的就是图纸审查。纸质版寄来寄去,丢件是常事。找起来像大海捞针。后来公司换了系统,确实省心不少。…

发布时间:2026/7/9 3:17:27
西安装修行业网站建设避坑指南:别花冤枉钱做模板

西安装修行业网站建设避坑指南:别花冤枉钱做模板

说实话,刚入行那会儿,我也觉得做个网站跟闹着玩似的。那时候觉得,找个淘宝店,几百块搞定,再套个现成的模板,发点案例图,完事。直到去年,我接了个急活,帮一个在曲江做高端私宅的设计师朋友梳理线上渠道。他之前也是这么干的,结果呢?客户咨询量倒是不少,但转化率极低…

发布时间:2026/7/9 4:31:56
博罗中山网站建设避坑指南:老板别再花冤枉钱做那种没人看的网页了

博罗中山网站建设避坑指南:老板别再花冤枉钱做那种没人看的网页了

做网站最怕啥? 不是钱花多了, 是钱扔水里听个响。很多老板找我吐槽, 说在博罗找团队做网站, 结果交完尾款, 网站打开慢得像蜗牛, 手机上看字还糊成马赛克。 这哪是建站啊, 这是给自家企业挖坑。特别是咱们博罗中山网站建设这块, 水太深, 外行根本看不出来。 你以为是高…

发布时间:2026/7/9 4:31:38
iPhone党别划走 | 华为FreeClip2真的不挑生态✨

iPhone党别划走 | 华为FreeClip2真的不挑生态✨

之前还刻板印象觉得华为耳机只适配鸿蒙或者安卓!!但用了之后真心被华子的FreeClip2惊艳到了,苹果用户终于能无门槛解锁旗舰级耳夹耳机体验👏之前很多人劝退,都是觉得iOS适配残缺、不值千元价!但近期多次固件…

发布时间:2026/7/9 4:31:15
产品经理如何选择兼顾原型和UI设计的软件?

产品经理如何选择兼顾原型和UI设计的软件?

产品经理选择兼顾原型和 UI 设计的软件,首推 [UXbot](https://www.uxbot.cn)。这是目前唯一能在同一工具内完成可视化流程规划、一次性生成 20 个以上页面可交互原型,并直接导出 HTML、Vue.js、Kotlin 和 Swift 多格式前端代码的 AI 工具,覆盖…

发布时间:2026/7/9 4:30:36
Claude:付费套餐对Claude Fable 5访问权限延长至7月12日

Claude:付费套餐对Claude Fable 5访问权限延长至7月12日

Claude延长付费套餐对Fable 5访问权限Claude宣布将所有付费套餐对Claude Fable 5的访问权限延长至7月12日。这一决策为付费用户提供了更充裕的时间去体验Claude Fable 5的各项功能。满足用户体验需求背后考量从用户角度来看,延长访问权限能让他们更深入地感受Claude…

发布时间:2026/7/9 4:30:36
终于搞懂了!对网站建设课程的心得体会分享,小白避坑指南

终于搞懂了!对网站建设课程的心得体会分享,小白避坑指南

说实话,刚开始报这个课的时候,我心里是打鼓的。 真的。 怕被割韭菜。 毕竟网上那些“三天精通建站”的广告太多了。 但我还是报了。 因为我想自己做个博客。 不想再依赖别人了。 那种感觉,就像是自己种菜,比买菜香。 虽然累点,但心里踏实。第一天上课,老师就讲HTML。 我听…

发布时间:2026/7/9 4:29:54
江苏建设个人信息网站 怎么查才不踩坑?

江苏建设个人信息网站 怎么查才不踩坑?

昨晚十一点半,我还在被窝里刷手机。不是看剧,是焦虑。前脚刚收到个骚扰电话,后脚短信就来了。那种感觉,就像有人在你家窗户底下装了窃听器。气不打一处来。我想查查我的信息到底泄露没。这时候脑子里蹦出个念头:江苏建设个人信息网站。别笑,这名字听着挺官方,挺靠谱。我…

发布时间:2026/7/9 0:01:26
珠海住房和建设局网站怎么查备案?老中介的掏心窝子话,别等踩坑才后悔

珠海住房和建设局网站怎么查备案?老中介的掏心窝子话,别等踩坑才后悔

珠海这地方,买房的人是真多,但水也是真深。很多人第一反应是去中介门店看海报,或者刷短视频听主播喊口号。说句不好听的,那些都是包装出来的“美好”。真正能定心丸的,其实就在那个看起来有点丑、操作有点繁琐的官方平台上——珠海住房和建设局网站。我干了五年房产,见过…

发布时间:2026/7/9 0:01:49
别再被忽悠了!揭秘专业网站建设效果的底层逻辑与真实成本

别再被忽悠了!揭秘专业网站建设效果的底层逻辑与真实成本

很多老板找我聊网站,开口就是“给我整一个高大上的”,预算还卡得死死的,三五千块钱想做出几十万的效果。说实话,这种需求我一般直接劝退。为啥?因为专业网站建设效果从来不是靠堆砌特效或者套用模板能搞定的,它是商业逻辑、技术实现和用户心理的精密结合。今天咱不整那些…

发布时间:2026/7/9 0:01:56
做个人信息管理网站建设,这3个坑我踩了七年,你千万别再跳

做个人信息管理网站建设,这3个坑我踩了七年,你千万别再跳

做了七年建站,见过太多老板花大钱买模板,最后发现根本没法用。特别是现在大家都讲究数据隐私,想搞个个人信息管理网站建设,结果越搞越乱。这篇文不整虚的,直接说怎么把这套系统落地,让你自己的数据真正听话。先说个真事儿。去年有个做自由职业的朋友找我,他说想建个网站…

发布时间:2026/7/8 14:09:51
杨凌规划建设局网站怎么查最新规划?老杨说点大实话

杨凌规划建设局网站怎么查最新规划?老杨说点大实话

杨凌规划建设局网站你是不是也遇到过这种情况?想看看自家旁边要修路,还是建公园。翻遍了手机,搜出来的全是几年前的旧闻。或者好不容易找到个入口,页面加载慢得像蜗牛。心里那个急啊,真的,懂的人都懂。我是老杨,在杨凌混了十几年,跟这行打交道不少。今天不跟你扯那些虚…

发布时间:2026/7/8 12:11:30
杭州网站建设 seo 避坑指南:别被那些只会套模板的忽悠了

杭州网站建设 seo 避坑指南:别被那些只会套模板的忽悠了

昨天半夜两点,我还在改一个客户的后台,咖啡都凉透了。这哥们儿是做机械配件的,在余杭那边,找的前一家公司花了八千块做了个站,结果上线一个月,百度连个影子都没有。他急得给我打电话,说是不是被黑了。我让他把链接发过来,打开一看,好家伙,那代码乱得跟刚被猫抓过的毛…

发布时间:2026/7/8 4:42:51
建站7年才悟出的网站建设思路,别再花冤枉钱了

建站7年才悟出的网站建设思路,别再花冤枉钱了

做建站这行整整7年了。 见过太多老板花几万块, 最后做出来的网站像个垃圾场。 今天不整那些虚头巴脑的术语。 就聊聊我踩过的坑, 和真正能落地的网站建设思路。很多老板一上来就问: “多少钱能做个高大上的?” 我通常直接劝退。 因为方向错了, 你给再多钱也是打水漂。 真正…

发布时间:2026/7/8 9:56:13
合肥的网站建设避坑指南:别被低价忽悠,这3个细节决定生死

合肥的网站建设避坑指南:别被低价忽悠,这3个细节决定生死

做企业官网最怕什么?不是技术难,是交钱后没人管,或者上线一个月连个访客都没有。这篇东西不扯虚的,直接告诉你怎么在合肥找个靠谱的团队,或者自己怎么避坑。先说个大实话,我在合肥混这行五年多,见过太多老板因为贪便宜吃大亏。你去百度搜“合肥的网站建设”,出来一堆报…

发布时间:2026/7/8 3:06:40
别被忽悠了!德州网站建设那些坑,我拿真金白银换来的教训

别被忽悠了!德州网站建设那些坑,我拿真金白银换来的教训

做这行久了,心里就憋着一股火。每次看到客户拿着网上抄来的模板,问我能不能做成“苹果官网”那种效果。我就想笑。真的,太想笑了。今天咱不整那些虚头巴脑的专业术语。就聊聊德州网站建设里,那些让人头秃的真实事儿。我有个客户,老张。他是做德州本地建材的,实在人。当初…

发布时间:2026/7/8 11:22:51