电子说
最近的C++项目中,需要用到消息队列,但是C++中又没有原生的消息队列,就在网上找了一下相关资料,利用C++提供的队列,自己封装一个消息队列,以后的项目也可以复用。话不多说,下面开始。
用到的对象:std::queue, std::condition_variable,std::mutex
提供的方法:push,poll,wait,wait_for
1、接口定义
1.1、推送消息
将消息推送进消息队列,并发送一次通知;
void push(const T &message)
1.2、轮询消息
从消息队列里取消息,无论消息队列里是否有消息,都立即返回。
/**
* @return true get message success
* @return false message queue is empty
*/
bool poll(T &message)
1.3、等待消息
这个方法是同步的,如果消息队列是空的,会一直阻塞在这里,直到接收到消息,才会返回。
void wait(T &message)
1.4、超时等待消息
这个方法也是同步的,不过可以设置超时时间,如果消息队列是空的会阻塞,直到收到消息或达到超时时间,才会返回。
std::cv_status wait_for(T &message, std::chrono::seconds timeOut)
2、用到的对象(私有成员,用于功能的实现)
2.1、队列
使用队列存放push进来的消息
#include
std::queue
2.2、条件变量
条件变量,用来实现消息的通知,push进来一个消息时,就会调一次notify
#include
std::condition_variable cv_;
2.3、互斥量
提供给条件变量使用的,也用作资源保护
#include
std::mutex mutex_;
下面是实现的源码:
使用模板的方式实现消息队列,只需要一个hpp文件就可以了。
#ifndef __MESSAGE_QUEUE_HPP__
#define __MESSAGE_QUEUE_HPP__
#include
#include
#include
template<class T>
class MessageQueue {
public:
void push(const T &message) {
std::lock_guard;
queue_.push(message);
cv_.notify_one();
}
/**
* @brief
*
* @param message
* @return true
* @return false
*/
bool poll(T &message) {
bool ret = false;
std::lock_guard;
if (queue_.size()) {
message = queue_.front();
queue_.pop();
ret = true;
}
return ret;
}
void wait(T &message) {
std::unique_lock;
while (!queue_.size()) {
cv_.wait(lock);
}
message = queue_.front();
queue_.pop();
}
std::cv_status wait_for(T &message, std::chrono::seconds timeOut) {
std::cv_status status(std::cv_status::no_timeout);
std::unique_lock;
if (!queue_.size()) {
status = cv_.wait_for(lock, timeOut);
}
if (std::cv_status::timeout != status) {
message = queue_.front();
queue_.pop();
}
return status;
}
size_t size(void) {
std::lock_guard;
return queue_.size();
}
private:
std::queue
3、测试验证
下面写一个测试用例:
#include "message_queue.hpp"
#include
#include
#include
typedef struct {
int flag;
} Message;
int main(int argc, char *argv[]) {
MessageQueue
编译命令:
g++ testmessage.cpp -lpthread
运行结果:
全部0条评论
快来发表一下你的评论吧 !