自学 (10) 消息队列

    技术2022-07-11  83

    定义

    *

    发展

    分类

    持续性

    键值

    打开/创建

    创建

    发送消息

    接受消息

    消息队列使用中的注意事项 以下内容转载于 https://blog.csdn.net/xiaobai1593/article/details/7408738

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

    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)

    用消息队列传输结构体

    方法一:

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

    如定义结构体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

    发送动态大小类型的消息

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

    1.消息的类型 mtype 不需为非0值。如果使用0,则msgsnd会失败,并得到”Invalid argument“错误。

    2.msgflg为0表示阻塞等待,如果msgflg为IPC_NOWAIT表示非阻塞。

    3.最好使用root权限执行消息队列,否则msgrcv 提示 “Permission denied”。

    Processed: 0.011, SQL: 9