linux进程间通信之Msgq

消息队列是进程间通信方式之一,该文章讲解如何使用消息队列,关于消息队列的基础知识,请同学们自行学习。

本列子实现一个简单的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来查看消息队列的消息情况。




你可能感兴趣的:(linux,消息队列,ipc,进程间通信)