Linux 进程间通信之消息队列的几点注意事项

1. 由于消息队列是属于内核的,因此在执行时,必须有Root权限才可以,否则会在访问消息队列时,出现EACCES错误,即访问权限的问题

2. msgbuf.mtype的设置

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

msgp指向结构体:

struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[1];    /* message data */
           };

mtext字段是一个数组,或是别的结构体

mtype字段必须是一个正整型数值(否则会导致错误:EINVAL)

3. 用消息队列传输结构体

方法一:

对上面的结构体进行字段的扩展的话,接收的时候会有问题

如定义结构体MsgBuf来发送和接收

typedef struct _MsgBuf
{
    int cmdType;
    int dataLen;
    char cmdContent[nCmdContentSize];
}MsgBuf, * pMsgBuf;

方法二:

不过可以让mtext来存储结构体中的内容,然后发送出去,即进行结构体的嵌套(可行)

需要注意的是,在发送嵌套的消息时,只能定义固定大小的结构体,即msgbuf.mtext字段是有长度固定字符数组

下例中传输一个结构体:

typedef struct _MsgType
{
    int dataLen;
    char sendName[16];
    char recvName[16];
    char data[128];
}MsgType, * pMsgType;

const int nMsgTypeSize=sizeof(MsgType);
发送代码如下:

    //mtext
    char tempBuf[nMsgTypeSize]={0};
    pMsgType msgType=(pMsgType)tempBuf;
    msgType->dataLen=10;
    strcpy(msgType->sendName, "BYH");
    strcpy(msgType->recvName, "ZQY");
    strcpy(msgType->data, "I love u");

    //填充消息
    MsgBuf sendBuf;
    sendBuf.mtype=1;
    memset(sendBuf.cmdContent, 0, nCmdContentSize);
    //将嵌套结构体的内容存储在msgbuf的字段mtext中
    memcpy(sendBuf.cmdContent, tempBuf, nMsgTypeSize);

    //成功返回0,否则返回-1
    int nRet=msgsnd(m_MsgQueueID, &sendBuf, nCmdContentSize, sflags);
    if(nRet==-1)
    {
        printf("向消息队列%d发送消息失败\n", m_MsgQueueID);
        printMsgSendErrorInfo(errno);
        return false;
    }

试验成功

输出结果如下:

从队列中接收消息成功
dataLen=10 sendName=BYHrecvName=ZQYdata=I love u

4. 发送动态大小类型的消息

这种好像比较纠结。因为,如果消息队列中的消息是不固定长度的,而且消息队列中有N条消息的话,由于可能会取多或者取少,从而导致整个消息队列的混乱


你可能感兴趣的:(Linux 进程间通信之消息队列的几点注意事项)