新闻中心
c++怎么实现一个线程安全的队列_c++多线程安全容器设计
线程安全队列通过std::mutex和std::condition_variable实现,确保多线程下push和pop操作的原子性与阻塞等待,适用于生产者-消费者模型。

在C++多线程编程中,实现一个线程安全的队列是常见需求,比如用于生产者-消费者模型。要保证多个线程同时访问队列时不会出现数据竞争或状态不一致,必须使用同步机制。下面介绍一种基于std::queue、std::mutex和std::condition_variable的安全队列实现方式。
基本设计思路
线程安全队列的核心目标是:多个线程可以安全地入队(push)和出队(pop),包括阻塞等待机制以提高效率。
关键点:
- 使用
std::mutex保护对内部队列的访问 - 使用
std::condition_variable实现线程等待非空/非满状态 - 提供
push和pop操作的原子性与阻塞性
代码实现示例
#include <queue>
#include <mutex>
#include <condition_variable>
#include <thread>
template<typename T>
class ThreadSafeQueue {
private:
std::queue<T> data_queue;
mutable std::mutex mtx;
std::condition_variable cv;
public:
ThreadSafeQueue() = default;
void push(T value) {
std::lock_guard<std::mutex> lock(mtx);
data_queue.push(std::move(value));
cv.notify_one(); // 唤醒一个等待的pop线程
}
bool try_pop(T& value) {
std::lock_guard<std::mutex> lock(mtx);
if (data_queue.empty()) {
return false;
}
value = std::move(data_queue.front());
data_queue.pop();
return true;
}
void wait_and_pop(T& value) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this] { return !data_queue.empty(); });
value = std::move(data_queue.front());
data_queue.pop();
}
bool empty() const {
std::lock_guard<std::mutex> lock(mtx);
return data_queue.empty();
}
size_t size() const {
std::lock_guard<std::mutex> lock(mtx);
return data_queue.size();
}
};
使用场景说明
这个队列适合大多数多线程协作场景:
易标AI
告别低效手工,迎接AI标书新时代!3分钟智能生成,行业唯一具备查重功能,自动避雷废标项
135
查看详情
-
生产者线程调用
push()添加任务 -
消费者线程调用
wait_and_pop()阻塞等待新任务 - 若不想阻塞,可用
try_pop()尝试获取元素
例如:
ThreadSafeQueue<int> task_queue;
// 生产者
auto producer = [&]() {
for (int i = 0; i < 5; ++i) {
task_queue.push(i
);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
};
// 消费者
auto consumer = [&]() {
int value;
for (int i = 0; i < 5; ++i) {
task_queue.wait_and_pop(value);
std::cout << "Consumed: " << value << "\n";
}
};
std::thread t1(producer);
std::thread t2(consumer);
t1.join(); t2.join();
注意事项与优化方向
虽然上述实现已满足基本线程安全需求,但仍有几点需要注意:
- 频繁加锁可能影响性能,可考虑无锁队列(如使用CAS操作)用于高并发场景
- 当前版本未支持超时弹出(如
wait_for或wait_until),可根据需要扩展 - 若需限制队列容量,可在
push中加入等待非满逻辑 - 注意异常安全:确保所有路径都正确释放锁
以上就是c++++怎么实现一个线程安全的队列_c++多线程安全容器设计的详细内容,更多请关注其它相关文章!
# 弹出
# 网站优化外包推广方案
# 普洱seo网络推广招聘
# 外贸如何做网站推广呢
# 贵阳英文网站推广
# 舟山租房网站建设
# seo 网站推广的八种方法
# 广元网站seo外包
# 江西百度网站推广
# 廊坊网站建设评价
# 网站推广方法联系火8星
# 之心
# ai
# 中文网
# 可在
# 相关文章
# 边缘
# 适用于
# 多个
# 游戏开发
# 多线程
# 同步机制
# 无锁
# c++
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
AI泡沫首次被“刺破”:GPU十年都无法存活!
如何修改开机登录密码_Windows账户安全设置超详细教程【必学】
狙击外星人小游戏开始_狙击外星人小游戏立即开始
深入理解J*a链表中的IPosition接口与使用
漫蛙2网页版漫画入口 漫蛙漫画在线官方登录
魅族17怎样用浏览器译外语网页_iPhone魅族17浏览器译外语网页【即时翻译】
PrimeNG Sidebar背景色自定义指南:CSS覆盖与主题化实践
优化Log4j2控制台输出性能:解决异步日志瓶颈
Python异步编程实践:使用Binance API构建实时交易数据流
Spring Boot内嵌服务器与J*a EE全栈特性:选择与部署策略
2026春节假期票务安排_2026春节放假购票指南
凉拌黄瓜怎么拌更入味 凉拌黄瓜简单家常做法
腾讯视频怎么举报不良内容_腾讯视频内容举报流程与违规信息处理方法
蛙漫移动版在线看 蛙漫手机浏览器直达入口
AO3最新入口2025公告_AO3中文官网合集
PHP 枚举:根据字符串获取枚举案例的策略与实现
一加Ace 6T支持全新明眸护眼:通过了最严苛的护眼小金标认证
如何使 Jest 模拟函数默认抛出错误以提高测试效率
Kafka Streams中基于消息头条件过滤消息的实现指南
如何为你的Composer包编写自动化测试_集成PHPUnit到Composer的scripts工作流
poki免费入口快捷访问 poki人气小游戏直接玩站点
2025-2030年全球乘用车销量预测:新能源成增长主力
抖音未来赚钱的新趋势 2025年值得关注的变现风口分析
Win11怎么合并任务栏图标 Win11开启任务栏合并减少图标占空间【方法】
R星幕后开发视频泄露 包含《GTA6》等多款大作
yandex入口引擎手机版 yandex安卓版下载入口
C++ typeid如何获取类型信息_C++ RTTI运行时类型识别用法
SteamMachine定价或为699美元 大家想入手吗?
1688商家版怎样分析买家画像精准供货_1688商家版分析买家画像精准供货【供货策略】
Lar*el表单中优雅地处理“返回”按钮以规避验证:最佳实践指南
冬*霸灯泡不亮怎么办_浴霸取暖灯一盏不亮的灯座清洁修复法
谷歌浏览器最新官方入口链接 谷歌浏览器网页版官网导航
特斯拉自动驾驶房车计划曝光 原型车将于2027年亮相
批改网学生版PC登录 批改网官网登录系统入口
J*aScript中高效管理与清空动态列表:避免循环陷阱
抖音DOU+怎么投最有效 抖音付费推广的ROI提升技巧
Safari怎么安装扩展程序 浏览器插件安装与管理方法【详解】
sublime怎么进行远程开发编辑_配置rsub/rmate实现sublime编辑服务器文件
搜狗浏览器如何使用密码生成器创建强密码 搜狗浏览器内置密码安全工具
解决macOS上安装pyhdf时‘hdf.h’文件缺失的编译错误
Golang如何使用buffered channel提高性能_Golang buffered channel优化技巧
QQ邮箱官方网站登录入口_QQ邮箱网页版在线使用
C#如何安全地从用户上传的XML文件中读取数据? 验证与清理策略
html怎么运行外部js文件中的函数_运html外js文件函数法【技巧】
Safari自带网页翻译功能怎么用 无需插件轻松看懂外文网站【方法】
网易大神账号申诉需要多久_网易大神账号申诉流程说明
消息称三星明年 2 月正式发布 HBM4,与 SK 海力士同台竞技
css卡片内容溢出如何处理_使用overflow隐藏或scroll显示内容
Golang指针如何与map组合使用_Golang map指针组合实践
文心一言怎样用插件调度API数据_文心一言用插件调度API数据【API调用】


2025-11-08
浏览次数:次
返回列表
);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
};
// 消费者
auto consumer = [&]() {
int value;
for (int i = 0; i < 5; ++i) {
task_queue.wait_and_pop(value);
std::cout << "Consumed: " << value << "\n";
}
};
std::thread t1(producer);
std::thread t2(consumer);
t1.join(); t2.join();