跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

如何用c++实现一个简单的消息队列(Message Queue) 模块解耦利器【架构设计】

C++轻量线程安全消息队列基于std::queue+mutex+condition_variable实现阻塞式生产者-消费者模型,支持模板泛型、移动语义、超时尝试及容量限制,兼顾解耦与健壮性。 用C++实现一个轻量、线程安全的消息队列,核心在于封装好生产者-消费者模型的同步逻辑,不依赖外部中间件,就能在模块间实现解耦。关键不是堆功能,而是把阻塞、通知、类型泛化这三点做稳。 用 标准库 组件搭出线程安全队列 不需要第三方库,C++11的 std::queue + std::mutex + std::condition_variable 就足够。重点是让Pop操作能自动等待——队列空时不忙等,而是挂起线程,等Push发来通知再唤醒。 用
std::unique_lock
保护所有队列读写操作 Pop时调用
cv.wait(lock, []{ return !q.empty(); })
,条件成立才继续 Push后立刻调用
cv.notify_one()
,只唤醒一个等待中的消费者 若需支持多消费者并行处理,notify_one比notify_all更节省资源 支持任意消息类型的模板设计 把队列定义成模板类,比如
template class BlockingQueue
,这样既能传
int
、
std::string
,也能传自定义结构体或智能指针,避免强制类型转换和内存管理混乱。 Push内部用
_queue.push(std::move(msg))
减少拷贝开销 Pop返回
bool
表示是否成功取到,配合引用参数输出值,避免异常路径下的资源泄漏 可选添加
TryPop(T&, int timeout_ms = 0)
支持带超时的非阻塞尝试 解耦场景下的典型用法 消息队列真正发挥价值的地方,是让两个原本紧耦合的模块变成“只认接口、不见对方”。比如日志模块不再直接调用文件写入函数,而是往队列里扔一条LogEntry;另一个独立线程从队列取日志、批量落盘。 C函数速查手册(CHM版) C函数速查手册(CHM版) 下载 立即学习 “ C++免费学习笔记(深入) ”; 生产者只需关注
queue.Push(log)
,不用管谁消费、何时消费、失败怎么重试 消费者专注处理逻辑,比如格式化+写文件+压缩归档,完全隔离业务主流程 如果某天要加Kafka上报,只需新增一个消费者线程,原系统代码零改动 注意边界与健壮性细节 简单不等于简陋。几个容易忽略但影响稳定性的点: 队列应设容量上限(如
max_size = 1024
),Push前检查,满则阻塞或丢弃/告警,防内存无限增长 提供
Close()
接口标记队列关闭,Pop检测到后主动退出循环,便于优雅停机 若需跨进程通信,可切换为Boost.Interprocess或POSIX消息队列,但单进程内优先用标准库,更可控

相关文章