您的位置:首页 > 运维架构 > Linux

linux进程通信:使用posix消息队列mq进行线程或进程间的通信

2014-09-01 15:27 2506 查看
POSIX消息队列允许进程以消息的形式交换数据。此API与System V消息队列(msgget(2),msgsnd(2),msgrcv(2)等)有明显不同,但做的事情差不多。

在linux多线程编程中,如果两个线程没用共同的数据区,则需要使用消息队列从一个线程往另一个线程发送消息(同样可以应用在进程间通信)

消息队列通过mq_open()创建和打开,此函数返回一个消息队列描述符mqd_t,它用于之后的调用中引用打开的消息队列。每个消息队列由一个名字标识,两个进程可以操作同一个队列。

消息通过调用mq_send()和mq_receive()传递。当一个进程结束使用该队列,则它调用mq_close(),当一个队列不再需要了,则可以调用mq_unlink()删除。队列属性可以调用mq_getattr()/mq_setattr()获取/修改。一个进程可以在一个空队列上调用mq_notify请求消息到达的异步通知。

消息队列描述符引用到一个打开的消息队列(类比open(2))。fock(2)之后,子进程继承父进程队列描述符的拷贝,两个描述符都引用到父进程的那个描述符。两个进程持有的描述符共享与消息队列描述符相关联的标记(mq_flags)。

下面以一个实例说明:

创建并接收数据线程:
#include<mqueue.h>
#define WAIT_FOREVER -1

typedef struct{
UINT32 start;
char name[32] = {0};
}MQ_SEND_MSG;                               //接收的消息结构体

char nameMsg[32] = {0};
UINT32 memAvail;
char chName;
MQ_SEND_MSG recvMsg;
extern mqd_t memAvailMsgQ;

struct mq_addr mqa;
mqa.mq_maxmsg = 20;
mqa.mq_msgsize = sizeof(MQ_SEND_MSG);
strcpy(nameMsg, "/memAvailMsgQ");
mqUnlink(nameMsg);

memAvailMsgQ = mq_open(nameMsg, O_CREAT|O_RDWR|O_EXCL, DEFAULT_MSG_MODE, &mqa);  //创建一个mq消息
if(memAvailMsgQ == -1)
{
return error;
}

FOREVER                                                 //循环等待另一个线程发送消息
{
retval = mq_receive(memAvailMsgQ, (char *)&recvSendMsg, sizeof(MQ_SEND_MSG), WAIT_FOREVER, NULL);
if(retval == sizeof(MQ_SEND_MSG))                   //mqReceive返回接收到的数据的长度,以此判断有没有成功接收消息
{
memAvail = recvSendMsg.start;
chName = recvSendMsg.name;
}
}
发送数据线程:

#include<mqueue.h>

typedef struct{
UINT32 start;
char name[32] = {0};
}MQ_SEND_MSG;                                //mq消息结构体

mqd_t memAvailMsgQ;                         //mq消息句柄

MQ_SEND_MSG mqSendMsg;
mqSendMsg.start = memAvail;                     //发送的消息结构体成员
strcpy(mqSendMsg.chName, "come on baby!");        //发送的消息结构体成员

mq_send(memAvailMsgQ, (char *)&mqSendMsg, sizeof(MQ_SEND_MSG), 200,  0);   //发送数据
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: