新闻中心
C++如何实现一个线程安全的队列?(代码示例)
使用unique_lock而非lock_guard是因为wait需自动释放并重获锁,而lock_guard不支持中途解锁。

用 std::mutex 配合 std::queue 和 std::condition_variable 就能写出一个真正可用的线程安全队列,核心是保护共享状态、避免忙等待、支持阻塞式读写。
基础模板:带锁+条件变量的阻塞队列
以下是一个泛型、线程安全、支持 push/pop 阻塞等待的队列实现:
#include <queue>
#include <mutex>
#include <condition_variable>
template <typename T>
class ThreadSafeQueue {
private:
std::queue<T> queue_;
mutable std::mutex mutex_;
std::condition_variable cond_not_empty_;
std::condition_variable cond_not_full_; // 可选:若加容量限制才需要
public:
void push(T value) {
std::lock_guard<std::mutex> lock(mutex_);
queue_.push(std::move(value));
cond_not_empty_.notify_one(); // 通知可能在 wait 的 pop
}
bool try_pop(T& result) {
std::lock_guard<std::mutex> lock(mutex_);
if (queue_.empty()) return false;
result = std::move(queue_.front());
queue_.pop();
return true;
}
void wait_and_pop(T& result) {
std::unique_lock<std::mutex> lock(mutex_);
cond_not_empty_.wait(lock, [this] { return !queue_.empty(); });
result = std::move(queue_.front());
queue_.pop();
}
};
为什么用 unique_lock 而不是 lock_guard 做 wait?
cond_not_empty_.wait() 必须传入 std::unique_lock,因为 wait 会自动释放锁、挂起线程,等被唤醒后再重新加锁。lock_guard 不支持中途解锁,无法配合 condition_variable 使用。
- wait 内部先 unlock,避免其他线程无法 push
- 唤醒后自动 re-lock,保证临界区安全
- 使用谓词(lambda)可防止虚假唤醒
要不要加容量限制?
如果希望队列有上限(比如避免内存爆掉),可以扩展:
bee餐饮点餐外卖小程序
bee餐饮点餐外卖小程序是针对餐饮行业推出的一套完整的餐饮解决方案,实现了用户在线点餐下单、外卖、叫号排队、支付、配送等功能,完美的使餐饮行业更高效便捷!功能演示:1、桌号管理登录后台,左侧菜单 “桌号管理”,添加并管理你的桌号信息,添加以后在列表你将可以看到 ID 和 密钥,这两个数据用来生成桌子的二维码2、生成桌子二维码例如上面的ID为 308,密钥为 d3PiIY,那么现在去左侧菜单微信设置
3
查看详情
立即学习“C++免费学习笔记(深入)”;
- 加成员变量 size_t capacity_
- push 前检查
q
ueue_.size() ,不满足则 wait(cond_not_full_) - pop 后 notify cond_not_full_,表示空出位置
- 注意 size() 在多线程下不是原子的——所以必须在锁内判断
更现代的选择:用 std::shared_mutex?
如果读远多于写(比如多个消费者只 pop,但只有一个生产者 push),可以用 std::shared_mutex 实现多读单写优化。不过标准 queue 的 pop 是修改操作,仍需独占锁;真正受益的是只读场景(如 size()、empty()),但通常这些调用本身开销小,优化意义不大。对绝大多数场景,std::mutex 已足够简洁高效。
基本上就这些。不需要自己造轮子,C++11 起的标准库原语完全够用,关键是把锁粒度、条件等待和移动语义用对。
以上就是C++如何实现一个线程安全的队列?(代码示例)的详细内容,更多请关注其它相关文章!
# 的是
# 湛江网站建设内容有哪些
# 株洲网站推广优化流程
# 江苏宁波网站优化排名
# 广水短视频seo
# 哪里有网站建设地址
# 南山网站优化化
# 天门新城推广员招聘网站
# seo必学5大技巧外推
# 沈阳资深seo
# 永泰有效的seo技术
# 边缘
# 是一个
# ai
# 解锁
# 中途
# 空出
# 不支持
# 如何实现
# 多线程
# 游戏开发
# red
# 为什么
# 标准库
# c++
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
Tailwind CSS line-clamp 布局问题解析与修复指南
天眼查怎么看公司融资情况 天眼查企业融资历史查询步骤【攻略】
晋江读书网页版在线登录 晋江读书电脑版官网
双系统安装时,如何设置默认启动系统? msconfig命令了解一下!
使用 Pandas 高效处理 .dat 文件:字符清理与数据计算
谷歌浏览器怎么给标签页静音_Chrome标签静音快捷操作
AO3官方镜像站点汇总 AO3同人作品网页版直达链接
魅族20怎样在浏览器开无图省流_iPhone魅族20浏览器开无图省流【流量节省】
如何在网页中实现特定地点的随机图片展示
厨房不锈钢水槽发黑生锈怎么处理_水槽用可乐+锡纸2分钟抛亮如新
抖音创作助手登录入口_抖音创作辅助工具官网直达
Bing引擎入口最新2025 Bing搜索免费官方登录
怎样把文件彻底粉碎无法恢复_Windows下安全删除敏感数据【隐私保护】
从J*aScript对象中精确提取指定属性的教程
J*aScript中管理异步API调用:确保操作顺序与数据一致性
C++ map遍历方法大全_C++ map迭代器使用总结
windows10怎么查看本机ip_windows10命令提示符ipconfig使用
Go语言中JSON数据解析与字段访问教程
在哪找SublimeJ远程工具_SFTP插件配置教程
J*a应用程序首次运行自动创建文件与目录的最佳实践
qq邮箱发邮件给国外发不出去_QQ邮箱国际邮件发送失败原因与解决
小红书商家版怎样在笔记嵌入商品卡路径_小红书商家版在笔记嵌入商品卡路径【挂载教程】
《马克思佩恩3》早期版本曝光 UI设计曾多次调整!
MAC怎么在地图App里使用“四处看看”_MAC体验部分城市的3D实景街景
在Go Martini框架中高效服务动态生成图像的实践指南
天猫2025双十一0点秒杀攻略 天猫爆款抢购时间
苹果手机如何防止被恶意App追踪
QQ邮箱网页版入口登录 QQ邮箱在线邮箱官方通道
J*aScript map 方法中处理循环元素为空数组的策略
格力空气能E5故障代码是什么情况_格力空气能E5代码解析与应对措施
树莓派传感器触发:通过Twilio API发送WhatsApp消息教程
poki网页游戏推荐_poki免费游戏平台入口
为什么我的微信朋友圈看不到别人的更新_微信朋友圈更新显示异常解决方法
在Qt QML中通过Python字典动态更新TextEdit内容的教程
天眼查企业查询官网入口 天眼查官方网页版查询
Win10系统怎么查看已安装更新_Win10卸载有问题的更新补丁
使用 Pandas 高效处理 .dat 文件:数据清洗与数值计算实战
微信网页版官方快速登录入口 微信网页版网页版账号直达
LINUX的I/O重定向是什么_深入理解LINUX中 >、>> 与 < 的区别
C++指针和引用有什么区别_C++内存管理核心概念深度解析
“在文档元素之后找到了标记”是什么错误? 检查并修复XML中多个根元素的3个方法
TikTok网页版直接登录 TikTok网页端官方平台入口
Composer如何在生产环境安全地执行composer update
qq游戏手机版下载安装_qq游戏移动端入口
Bilibili动漫最新防封地址发布-Bilibili动漫2025年最稳正版入口推荐
微信客户端如何收红包_微信客户端接收红包使用教程
PySpark中从现有列右侧提取可变长度字符创建新列的教程
必由学官网首页入口 必由学教师网页版登录指南
c++ 命名空间怎么用 c++ namespace使用指南
俄罗斯Yandex搜索引擎入口_Yandex官网免登录一键访问


2025-12-15
浏览次数:次
返回列表
ueue_.size() ,不满足则 wait(cond_not_full_)