消息队列是进程间通信方式之一,该文章讲解如何使用消息队列,关于消息队列的基础知识,请同学们自行学习。
本列子实现一个简单的client,server;client负责放置消息到消息队列中,server负责读出消息队列。
//MsgQ操作封装
#ifndef _MY_MSG_QUEUE_ #define _MY_MSG_QUEUE_ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string> class MsgQueue { public: MsgQueue():m_msgId(-1){} ~MsgQueue(){} #define MAX_LENGTH 1024*50 struct _msg_struct_ { long type; char msg[MAX_LENGTH]; //max buffer is 50k }; public: int InitQueue(unsigned int key) { if((m_msgId = msgget((key_t)key,0666|IPC_CREAT)) < 0 ) { m_errmsg = strerror(errno); return -1; } return 0; } int PutOne(const std::string str, long type = 9999) { if(m_msgId == -1) { m_errmsg = "Not Init"; return -1; } if(str.length() > MAX_LENGTH) { m_errmsg = "Msg Too large"; return -2; } struct _msg_struct_ s_data; s_data.type = type; memcpy(s_data.msg, str.c_str(), str.length()); int ret = msgsnd(m_msgId, (void*)&s_data, str.length(), IPC_NOWAIT); if(ret < 0) { m_errmsg = strerror(errno); return -3; } return 0; } int GetOne(std::string &strOut, long type = 0) { if(m_msgId == -1) { m_errmsg = "Not Init"; return -1; } struct _msg_struct_ s_data; ssize_t size = msgrcv(m_msgId, (void*)&s_data, MAX_LENGTH, type, IPC_NOWAIT); if(size < 0) { m_errmsg = strerror(errno); return -2; } strOut.assign(s_data.msg, size); return size; } std::string GetLastErrMsg() { return m_errmsg; } private: int m_msgId; std::string m_errmsg; }; #endif
Client实现如下
#include "MsgQueue.h" #include <iostream> #define MSG_KEY 11021 #define MSG_TYPE 11011 int main(int argc, char**argv) { MsgQueue msgQ; int iResult = msgQ.InitQueue(MSG_KEY); if(iResult) { std::cerr<<"Msgq Init Failed,ErrMsg:"<<msgQ.GetLastErrMsg()<<std::endl; return iResult; } std::string strMsg="www.google.hk.com"; iResult = msgQ.PutOne(strMsg,MSG_TYPE);//放置消息到msgq中 if(iResult) { std::cerr<<"Msgq PutOne Failed,ErrMsg:"<<msgQ.GetLastErrMsg()<<std::endl; return iResult; } std::cout<<"Client Put Msg Finished!!"<<std::endl; }Server的实现如下:
#include "MsgQueue.h" #include <iostream> #define MSG_KEY 11021 #define MSG_TYPE 11011 int main(int argc, char**argv) { MsgQueue msgQ; int iResult = msgQ.InitQueue(MSG_KEY); if(iResult) { std::cerr<<"Msgq Init Failed,ErrMsg:"<<msgQ.GetLastErrMsg()<<std::endl; return iResult; } std::string strMsg; iResult = msgQ.GetOne(strMsg,MSG_TYPE);//从msgq中读取消息 if(iResult<0) { std::cerr<<"Msgq GetOne Failed,ErrMsg:"<<msgQ.GetLastErrMsg()<<",Result:"<<iResult<<std::endl; return iResult; } std::cout<<"Server Get Msg Finished,Msg:"<<strMsg<<std::endl; }g++ server.cpp -o server
g++ client.cpp -o client
在生产和消费的过程中,可以通过系统命令ipcs来查看消息队列的消息情况。