news 2026/6/23 17:08:14

C++编程实践——条件变量中wait和std::unique_lock关系

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++编程实践——条件变量中wait和std::unique_lock关系

一、条件变量的用法

在讨论这个问题前,先看一下条件变量的基本用法,看一下代码:

bool m_signaled=false;std::mutex m_lockMutex;std::condition_variable m_cvLock;inlinevoidwait(){std::unique_lock<std::mutex>lock(this->m_lockMutex);while(!m_signaled){this->m_cvLock.wait(lock);}// After moving to the wait() function, prevent triggering loss 20240827m_signaled=false;}

在使用condition_variable时,大家可能会遇到信号丢失、假唤醒等行为。当然,对于很多种情况下,这都不是致命的问题。不过,作为一个优秀的开发者,一定会从代码层次消弥这些隐含的BUG(推荐看看陈硕大牛的博客中相关的分析)。
那条件变量中为什么使用std::unique_lock而不使用std::lock_guard呢?或者说,std::lock_guard在与条件变量共同协作是有什么问题呢?

二、wait和std::unique_lock

针对上面的问题,先看一下条件变量中wait的源码:

//wait apitemplate<typename _Predicate>voidwait(unique_lock<mutex>&__lock,_Predicate __p){while(!__p())wait(__lock);}//call the following apitemplate<typename _Lock>voidwait(_Lock&__lock){shared_ptr<mutex>__mutex=_M_mutex;unique_lock<mutex>__my_lock(*__mutex);_Unlock<_Lock>__unlock(__lock);// *__mutex must be unlocked before re-locking __lock so move// ownership of *__mutex lock to an object with shorter lifetime.unique_lock<mutex>__my_lock2(std::move(__my_lock));_M_cond.wait(__my_lock2);}template<typename _Lock,typename _Predicate>voidwait(_Lock&__lock,_Predicate __p){while(!__p())wait(__lock);}template<typename _Lock>struct_Unlock{explicit_Unlock(_Lock&__lk):_M_lock(__lk){__lk.unlock();}#pragmaGCC diagnostic push#pragmaGCC diagnostic ignored"-Wdeprecated-declarations"~_Unlock()noexcept(false){if(uncaught_exception()){__try{_M_lock.lock();}__catch(const__cxxabiv1::__forced_unwind&){__throw_exception_again;}__catch(...){}}else_M_lock.lock();}#pragmaGCC diagnostic pop_Unlock(const_Unlock&)=delete;_Unlock&operator=(const_Unlock&)=delete;_Lock&_M_lock;};

在上面的代码中,可以清楚的看到在wait中使用了Predicate(谓词),最重要的是在调用的内部API中wait(_Lock& __lock)中调用了Unlock。而std::unique_lock封装提供的接口恰恰提供了相关的接口操作,但std::lock_guard中却没有提供类似的机制。
莫非这就是条件变量中的wait必须使用std::unique_lock的原因?

三、分析和说明

既然从上层的应用到wait的源码中,都看到wait和std::unique_lock的紧密纠结。那么可以就此展开分析一下,看看到底什么原因导致wait中必须使用std::unique_lock。从应用可以倒推过来:

  1. 条件变量的假唤醒
    假唤醒这个问题是Linux内核中存在的,如果想解决这个问题,就需要一种机制来处理(如果看过陈硕的相关博客则非常容易理解)。也就是说,需要一个锁+布尔变量来控制假唤醒。那么假唤醒有什么风险呢?大多数情况下,假唤醒其实一点都不影响多线程间的操作。但如果在类似生产者和消费者队列操作时,假唤醒极有可能导致意外数据读取异常。在某些情况下甚至可能导致程序的崩溃。
    而std::lock_guard只是一个简单的RAII封装,没有提供其它的接口,导致在锁+布尔变量操作时,无法显式的控制锁的释放和再锁住,也就是上面提到的wait中的Unlock。而恰恰这些情况,std::unique_lock都可以满足(可以回想一下std::unique_lock的所权独占、转移以及超时、延时等等,此处不再展开)。也就是说,通过std::unique_lock可以让wait在需要的时机随时释放和锁住相关资源,既方便又灵活还防止了死锁的可能。
  2. 信号的丢失
    信号丢失的原因,一般是发送与接收不匹配。在多线程中,大家往往无法预判信号发送线程和信号接收线程的时机。而锁的出现,可以保证信号的发送和接收的同步,这就避免了信号的丢失(wait中的互斥锁)。

也就是说,条件变量中的wait,需要锁提供更丰富和细节的接口安全保证,而这不是std::lock_guard能满足的,但std::unique_lock却恰恰能够满足。std::unique_lock仅以少量的性能损失,就提供了更多的灵活性,所以条件变量与其合作完成多线程的操作是一种必然。

四、总结

在前面分析了std::unique_lock的具体应用。但如果想融会贯通std::unique_lock的实践,就需要有一个实际的应用场景来体现出来。而多线程编程作为一种难度较大的情况更能体现其设计的底层目标,特别是针对条件变量wait的操作,能够让开发者更深刻的理解std::unique_lock。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 23:00:38

激光雪深监测站的原理与功能特点

在冬季&#xff0c;降雪带来的积雪深度变化&#xff0c;对交通、气象、农业、建筑等诸多领域有着不可忽视的影响。传统雪深监测手段存在精度欠佳、实时性不足、易受环境干扰等问题&#xff0c;难以满足现代监测需求。激光雪深监测站凭借先进技术&#xff0c;为雪深监测带来了全…

作者头像 李华
网站建设 2026/6/23 15:45:38

PCB镀金未来之路:绿色化、纳米化与智能化

当电子产品迈向高频高速&#xff0c;PCB镀金工艺正经历一场技术革命。从剧毒氰化物到环保无氰电镀&#xff0c;从微米级到纳米级厚度控制&#xff0c;再到AI驱动的智能产线&#xff0c;镀金技术如何与时俱进&#xff1f;本期展望镀金工艺的未来图景。​绿色转型&#xff1a;无氰…

作者头像 李华
网站建设 2026/6/23 19:00:14

利用镜像条形图探索Erasmus项目

利用镜像条形图探索Erasmus项目 import pandas as pd import numpy as np import matplotlib.pyplot as plt数据探索 以下数据如果有需要的同学可关注公众号HsuHeinrich&#xff0c;回复【数据可视化】自动获取&#xff5e; resume_url https://raw.githubusercontent.com/ho…

作者头像 李华
网站建设 2026/6/23 18:20:40

终极免费WordPress页面构建利器:PRO Elements完全使用指南

终极免费WordPress页面构建利器&#xff1a;PRO Elements完全使用指南 【免费下载链接】proelements This plugin enables GPL features of Elementor Pro: widgets, theme builder, dynamic colors and content, forms & popup builder, and more. 项目地址: https://gi…

作者头像 李华
网站建设 2026/6/23 18:20:04

FanControl终极指南:快速解决Windows风扇控制难题

你是否曾为电脑风扇的噪音而烦恼&#xff1f;玩游戏时突然的"高速运转"&#xff0c;或者待机时风扇不规则地忽快忽慢&#xff1f;FanControl正是为解决这些散热控制问题而生的专业工具。在本文中&#xff0c;你将立即掌握这款软件的完整使用流程&#xff0c;从基础安…

作者头像 李华
网站建设 2026/6/23 14:01:33

M.I.B.汽车系统定制指南:新手也能轻松解锁隐藏功能

你是否曾经对汽车原厂系统的功能限制感到困扰&#xff1f;为什么高端汽车的信息娱乐系统不能像智能手机一样自由定制和扩展&#xff1f;如果你的车载系统是Harman MHIG或MHI2/MHI2Q系列&#xff0c;那么M.I.B.正是你一直在寻找的解决方案。 【免费下载链接】M.I.B._More-Incred…

作者头像 李华