【Linux篇】消息队列

一、什么是消息队列 

消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识。

二、特点

  1. 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。

  2. 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。

  3. 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

三、常用API

1.创建/打开消息队列

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
 
int msgget(key_t key, int msgflg);
 
参数:
key_t key:   创建新的消息队列
int msgflg:  赋予新消息队列的权限,如:IPC_CREAT|0777

2.添加消息

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
 
参数:
int msqid:          消息队列标识符
const void *msgp:   msgp是一个任何类型的结构体,是消息队列的地址
size_t msgsz:       要发送消息的大小,不含消息类型占用的4个字节,即mtext的长度
int msgflg:          默认写0:当消息队列满时,msgsnd将会阻塞,直到消息能写进消息队列
 
const void *msgp的结构体如下:
struct msgbuf {
        long mtype;       /* message type, must be > 0 */
        char mtext[128];    /* message data */
};

3.读取消息

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
 
参数:
int msqid:      消息队列标识符
void *msgp:     存放消息的结构体,结构体类型要与msgsnd函数发送的类型相同
size_t msgsz:   要接收消息的大小,不含消息类型占用的4个字节
long msgtyp:    要读消息的类型,如写:888
int msgflg:     默认写0: 阻塞式接收消息,没有该类型的消息msgrcv函数一直阻塞等待
 

4.控制消息队列

int msgctl(int msqid, int cmd, struct msqid_ds *buf);


参数:
int msqid:           消息队列标识符
int cmd:             一般写IPC_RMID
struct msqid_ds *buf:一般写NULL
返回值:成功返回0,失败返回-1

5.ftok

系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值。通常情况下,该id值通过ftok函数得到。

key_t ftok( char * fname, int id );

参数:
fname就时你指定的文件名(该文件必须是存在而且可以访问的)
id是子序号,虽然为int,但是只有8个比特被使用(0-255)。
返回值:
当成功执行的时候,一个key_t值将会被返回,否则 -1 被返回。

四、编程示例

msgGet.c

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

struct msgbuf{
	long mtype;
	char mtext[128];
};

int main()
{
	struct msgbuf readBuf;
	struct msgbuf sendBuf = {988,"Thank you,welcome"};

	key_t key;
	key = ftok(".",'z');//获取key值
	printf("key=%x\n",key);

	int msgid = msgget(key,IPC_CREAT|0777);//获取消息队列
	if(msgid == -1){
		printf("get queue failed\n");
	}
	
	msgrcv(msgid,&readBuf,sizeof(readBuf.mtext),888,0);//从消息队列读取内容
	printf("read from queue:%s\n",readBuf.mtext);

	msgsnd(msgid,&sendBuf,strlen(sendBuf.mtext),0);//往消息队列写入内容

	msgctl(msgid,IPC_RMID,NULL);

	return 0;
}

msgSend.c

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

struct msgbuf{
	long mtype;
	char mtext[128];
};

int main()
{
	struct msgbuf sendBuf = {888,"this is message from queue"};
	struct msgbuf readBuf;

	key_t key;
	key = ftok(".",'z');//获取key值
	printf("key=%x\n",key);

	int msgid = msgget(key,IPC_CREAT|0777);//获取消息队列
	if(msgid == -1){
		printf("get queue failed\n");
	}

	msgsnd(msgid,&sendBuf,strlen(sendBuf.mtext),0);//往消息队列发送内容
	printf("send over\n");

	msgrcv(msgid,&readBuf,sizeof(readBuf.mtext),988,0);//从消息队列读取内容
	printf("return from get:%s\n",readBuf.mtext);

	msgctl(msgid,IPC_RMID,NULL);

	return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿gao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值