1.消息队列的概念:
消息队列是一种临时存储消息的队列,可以完成进程间的数据传递。
即消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。
2.消息队列的操作
(1)创建和访问消息队列(使用shmget函数实现)
int shmget((key_t)key,size_t size,int flag);
key是键值,程序必须提供一个键来命名某个特定的消息队列。
flag是访问权限以及控制,一般使用IPC_CREAT 含义是:如果文件存在就直接获取,如果文件不存在就创建。
成功时
它的返回值为消息队列的标识符msgid,失败时返回-1。
(2)发送消息(使用msgsnd函数)
该函数用来把消息添加到消息队列中
int msgsend(int msgid, const void *msg_ptr, size_t size,int flag);
msgid是由msgget函数返回的消息队列标识符。msg_ptr是一个指向结构体的指针,该结构体里面包括了消息的类型+数据,size是数据的大小。
(3)获取消息(使用msgrcv函数)
int msgrcv(int msgid, void *msg_ptr, size_t size,long int type, int flag);
type是数据类型
(4)删除消息队列(使用 msgctl函数)
int msgctl(int msgid, int command, struct msgid_ds *buf);
command是将要采取的动作,它可以取3个值,
IPC_STAT:把msgid_ds结构中的数据设置为消息队列的当前关联值,即用消息队列的当前关联值覆盖msgid_ds的值。
IPC_SET:如果进程有足够的权限,就把消息列队的当前关联值设置为msgid_ds结构中给出的值
IPC_RMID:删除消息队列
buf是指向msgid_ds结构的指针
3.代码示例:
A进程:
#include
#include
#include
#include
#include
#include
#include
#include
struct msgbuff
{
long type;//数据类型
char data[128];//该数组存放数据
};
void main()
{
int msgid = msgget((key_t)1234, IPC_CREAT | 0664);//获取和访问消息队列
assert(msgid != -1);
struct msgbuff buff;
buff.type = 1;//设数据类型 为1
strcpy(buff.data, "hello");//拷贝 hello 给该数据
msgsnd(msgid, &buff, strlen(buff.data), 0); // 最后一个参数是权限 0代表可读可写
buff.type = 2;
strcpy(buff.data, "world");
msgsnd(msgid, &buff, strlen(buff.data), 0);//发送消息
}
B进程:
#include
#include
#include
#include
#include
#include
#include
#include
struct msgbuff
{
long type;
char data[128];
};
void main()
{
int msgid = msgget((key_t)1234,IPC_CREAT | 0664);
assert(msgid != -1);
struct msgbuff buff;
memset(&buff, 0,sizeof(buff));//将buff里的数据置空
msgrcv(msgid, &buff, 127, 1000,0);//接收消息
printf("%s\n",buff.data);
}
4.消息队列与信号量、管道的对比
消息队列与信号量对比:都是以内核对象来确保访问同一个数据。
信号量进行进程的同步控制,消息队列发送实际的数据。
消息队列与管道相比:管道发送的数据没有类型,读取数据端无差别从管道中按照数据的先后顺序读取数据,消息队列数据有类型,读端可以根据数据类型读取特定的数据。