C++11 实现消息队列

3,238 阅读1分钟

前言

在多线程场景下,我们可以使用锁、条件变量以及信号量来解决同步问题。而使用线程安全的消息队列几乎可以解决绝大部分开发问题。

golang中可以使用channel,c++则需要我们自己来造轮子。最近项目有用到,因此实现了一个简单的消息队列。

代码

#include <mutex>
#include <condition_variable>
#include <queue>

template<typename T>
class MsgQueue {
private:
    std::deque<T> q_;
    std::mutex mtx_;
    std::condition_variable cdv_;
public:
    // 传入一条消息,队列长度未做限制
    void push(T data) {
        std::unique_lock<std::mutex> lock(mtx_);
        q_.push_back(data);
        cdv_.notify_one();  //唤醒一个阻塞的线程
    }

    // 获取一个消息,若队列为空,则阻塞等待
    T pop() {
        std::unique_lock<std::mutex> lock(mtx_);
        while (q_.empty())
        {
            cdv_.wait(lock);
        }
        auto ret = std::move(q_.front());
        q_.pop_front();
        return ret;
    }

    // 获取队列长度
    size_t size() {
        std::unique_lock<std::mutex> lock(mtx_);
        return q_.size();
    }
};

开源项目

若简单实现的消息队列无法满足要求,还有一些比较出名的c++开源项目可供选择。

concurrentqueue 是一个 C++的工业级无锁队列。对使用者而言值得注意的特性如下:

  • 完全线程安全的无锁队列。从任意数量的线程并发使用。
  • 不需要编译。该项目是一堆头文件,只需要将头文件放入项目中就可以使用。
  • 不保证消息顺序的一致性!对消息顺序有要求的话不可使用该队列。

MPMCQueue 是用 C++11 编写的有界多生产者多消费者并发队列。