消息队列

消息就是数据,队列在数据结构中学到过,其特点是先进先出。在这里消息不仅仅是数据,还包括类型,我们获取消息时有优先级。因为消息有类型,我们获取消息时可以选择优先获取哪种类型的数据。消息队列是一种临时储存消息的队列,完成进程间的数据传递。


与信号量对比:都是以内核对象来确保多进程访问同一个消息队列,信号量进行进程同步控制,消息队列发送实际数据。

与管道对比:管道发送的数据没有类型,读取数据端无差别的从管道中按先后顺序读取数据,消息队列数据有类型,读端根据数据类型读取特定的数据。


接下来就是操作:

1、创建/获取:int msgget(key_t key, int flag);

key就是键值,与其他IPC一样。

flag是权限以及控制。按位或IPC_CREAT,如果存在直接获取;如果不存在则创建。

成功返回消息队列ID,失败返回-1.

2、发送消息:int msgsnd(int msgid,void*ptr,size_t size,int flag);

msgid 就是消息队列ID,指定是哪一个消息队列,通过msgget函数得到。

ptr 指向一个结构体,定义了要发送的数据和类型。

size 数据的大小。

flag 控制当前消息队列满或消息队列达到系统限制时将要发生的事情,如果设置了IPC_NOWAIT标志函数将立刻返回,不发送消息且返回值为-1,如果没有则发送进程将挂起以等待队列中腾出可用空间。

成功返回0,失败返回-1。如果成功,消息数据的一份副本放到消息队列中。

3、获取消息:int msgrcv(int msgid,void*ptr,size_t size,long type,int flag);

msgid 就是消息队列ID,指定是哪一个消息队列,通过msgget函数得到。

ptr 可以理解成一个char*buff,把获取到的数据放到buff中。

size 就是buff的大小。

type 数据类型,就是我们要获取哪种类型的数据。

 type==0 返回队列中的第一个消息。 

 type > 0 返回队列中消息类型为type的第一个消息。 

 type < 0 返回队列中消息类型值小于或等于type绝对值的消息,如果这种消息有若干个,则取类型值最小的消息。

flag 控制当前队列中没有相应类型的消息可以接收时将发生的事,如果设置了IPC_NOWAIT标志函数将立刻返回,返回值为-1,如果没有则发送进程将挂起以等待一条相应类型的消息。

成功时返回放到缓存区的字节数,消息被复制到ptr指定的缓存区,然后删除消息队列中的对应的消息。失败时返回-1。

4、删除消息队列:int msgctl(int msgid, int cmd,struct msgid_ds *buff);

msgid 就是消息队列ID,指定是哪一个消息队列,通过msgget函数得到。

cmd 指定进行什么操作,

IPC_STAT   把msgid_ds结构体中的数据设置为消息队列的当前关联值;

IPC_SET    把消息队列的当前关联值设置成msgid_ds结构体中给出的值;

IPC_RMID  删除消息队列。

成功返回0,失败返回-1。如果删除消息队列时,某个进程正在msgsnd或msgrcv等待,这两个函数将失败。


下面是一个简单的例子

msga.c

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>

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 = 1000;
	strcpy(buff.data, "hello");

	msgsnd(msgid, &buff, strlen(buff.data), 0);

	buff.type = 2000;
	strcpy(buff.data, "world");

	msgsnd(msgid, &buff, strlen(buff.data), 0);
}

msgb.c

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>

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));

	msgrcv(msgid, &buff, 127, 1000, 0);

	printf("%s\n", buff.data);

}
结果如下:



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值