在C++中,并没有直接提供消息队列(Message Queue)的标准库实现。但是,你可以使用std::queue
与std::mutex
(或std::lock_guard
)、std::condition_variable
等工具自己实现一个简单的线程安全消息队列。以下是一个简单的示例:
#include <queue>
#include <mutex>
#include <condition_variable>
#include <stdexcept>
template <typename T>
class MessageQueue {
public:
MessageQueue() = default;
~MessageQueue() = default;
// 禁止拷贝构造和拷贝赋值
MessageQueue(const MessageQueue&) = delete;
MessageQueue& operator=(const MessageQueue&) = delete;
// 移动构造和移动赋值
MessageQueue(MessageQueue&& other) noexcept : _queue(std::move(other._queue)),
_mutex(std::move(other._mutex)),
_cv(std::move(other._cv)) {
other._cv = std::condition_variable(); // 重置条件变量
}
MessageQueue& operator=(MessageQueue&& other) noexcept {
if (this != &other) {
_queue = std::move(other._queue);
_mutex = std::move(other._mutex);
_cv = std::move(other._cv);
other._cv = std::condition_variable(); // 重置条件变量
}
return *this;
}
void push(T new_value) {
std::lock_guard<std::mutex> lock(_mutex);
_queue.push(std::move(new_value));
_cv.notify_one(); // 通知等待的线程
}
T pop() {
std::unique_lock<std::mutex> lock(_mutex);
_cv.wait(lock, [this]{ return !_queue.empty(); }); // 等待队列非空
T popped_value = std::move(_queue.front());
_queue.pop();
return popped_value;
}
bool try_pop(T& value) {
std::lock_guard<std::mutex> lock(_mutex);
if (_queue.empty()) {
return false;
}
value = std::move(_queue.front());
queue_.pop();
return true;
}
//轮询消息
bool poll(T& msg) {
std::unique_lock<std::mutex> lock(_mutex);
if (_queue.size())
{
msg = _queue.front();
_queue.pop();
return true;
}
return false;
}
//等待消息
void wait(T& msg) {
std::unique_lock<std::mutex> lock(_mutex);
while (!_queue.size())
_cv.wait(lock);
msg = _queue.front();
_queue.pop();
}
//队列长度
size_t size() {
std::unique_lock<std::mutex> lock(_mutex);
return _queue.size();
}
bool empty() const {
std::lock_guard<std::mutex> lock(_mutex);
return _queue.empty();
}
private:
std::queue<T> _queue;
mutable std::mutex _mutex;
std::condition_variable _cv;
};
这个MessageQueue
类模板提供了一个线程安全的消息队列。它使用std::queue
来存储消息,使用std::mutex
来同步访问,并使用std::condition_variable
来在队列为空时阻塞pop
操作,以及在有新消息时通知等待的线程。
这个实现允许你在多线程环境中安全地推送和弹出消息。请注意,push
操作是非阻塞的,而pop
操作会阻塞直到队列中有消息。此外,还提供了一个try_pop
方法,该方法尝试从队列中弹出消息,如果队列为空,则返回false
。
需要注意的是,这个实现是基本的,并且可能不适合所有用例。例如,它并没有处理生产者或消费者过多的情况,这可能导致队列的大小无限增长。在实际应用中,你可能需要添加一些额外的逻辑来处理这种情况,例如限制队列的大小,或者在队列满时阻塞生产者。