ipc对象之消息队列

ipc对象之消息队列

1.概念

消息队列是System V IPC对象的一种,用来进程间通信

消息队列由消息队列ID来唯一标识

消息队列是一个消息的列表。用户可以在消息队列中添加消息、读取消息

消息队列可以按照类型来发送、接收消息

在内核空间是以链表的形式存储的

在这里插入图片描述

2.相关API

合成key值

#include <sys/types.h>
#include <sys/ipc.h>

key_t ftok(const char *pathname,int proj_id)
	pathname:一个存在的文件或目录名
	proj_id:0~255之间的非负整数
	成功返回key值,失败返回-1

创建消息队列通道

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

int msgget(key_t key,int flag)
	key:和消息队列相关联的key值
	flag:消息队列的访问权限
	成功返回消息队列ID,出错返回-1

添加消息

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

int msgsnd(int msqid,const coid *msgp,size_t size,int flag)
	msqid:消息队列的ID
	msgp:指向消息的指针。常用消息结构msgbuf如下:
	struct msgbuf
	{
		long mtype;		//消息类型
		char mtext[N]; //消息正文
	}
	size:发送的消息正文的字节数
	flag:
		IPC_NOWAIT消息没有发送完成函数也会立即返回。
		0直到发送完成函数才返回
	成功返回0,出错返回-1

读取消息

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg,h>

int msgrcv(int msgid,void *msgp,size_t size,long msgtype,int flag)
	msqid:消息队列的ID
	msgp:接收消息的缓冲区
	size:要接受的消息正文的字节数
	msgtype:
		0:接收消息队列中第一个消息
		大于0:接收消息队列中第一个类型为msgtyp的消息
		小于0:接收消息队列中类型值不大于msgtyp的绝对值且类型值又最小的消息
	flag:
		0:若无消息函数会一直阻塞
		IPC_NOWAIT:若没有消息,进程会立即返回ENOMSG
	成功接收到消息的长度,出错返回-1

删除消息队列

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

int msgctl(int msgqid,int cmd,struct msqid_ds *buf)
	msqid:消息队列的队列ID
	cmd:
		IPC_STAT:读取消息队列的属性,并将其保存在buf指向的缓冲区中
		IPC_SET:设置消息队列的属性。这个值取自buf参数
		IPC_RMID:从系统中删除消息队列
	bus:消息队列缓冲区
	成功返回0,出错返回-1
3.测试

msgwrite.c

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

#define N 128
#define MSGLEN (sizeof(MSGT) - sizeof(long))

/* 定义通信结构体 */
typedef struct msgbuf
{
	long mtype;		/* 类型 */
	char mtext[N];  /* 数据 */
}MSGT;

int main()
{
	key_t key;
	int msgid = 0;
	int ret = 0;
	/* 合成key值 */
	key = ftok(".",3);
	if(key < 0)
	{
		perror("ftok error\n");
		return -1;
	}
	/* 创建消息队列 */
	msgid = msgget(key,IPC_CREAT|0666);
	if(msgid < 0)
	{
		perror("msgget error\n");
		return 0;
	}
	/* 赋值 */
	MSGT data = {1L,"hweriwe"};
	//scanf("%ld %s",&data.mtype,data.mtext);
	/* 发送消息 */
	ret = msgsnd(msgid,&data,MSGLEN,0);
	if(ret < 0)
	{
		perror("msgsnd error\n");
		return -1;
	}

	return 0;
}

msgread.c

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


#define N 128
#define MSGLEN (sizeof(MSGT) - sizeof(long))

typedef struct msgbuf
{
	long mtype;
	char mtext[N];
}MSGT;


int main()
{
	key_t key;
	int ret = 0;
	MSGT data;
	int msgid = 0;
	/* 合成key值 */
	key = ftok(".",3);
	if(key < 0)
	{
		perror("ftok error\n");
		return -1;
	}
	/* 创建消息队列 */
	msgid = msgget(key,IPC_CREAT|0666);
	if(msgid < 0)
	{
		perror("msgget error\n");
		return -1;
	}
	/* 接收消息 */
	ret = msgrcv(msgid,&data,MSGLEN,0,0);
	if(ret < 0)
	{
		perror("msgrcv error\n");
	}
	printf("mtype:%ld mtext:%s\n",data.mtype,data.mtext);
	/* 销毁消息队列 */
	msgctl(msgid,IPC_RMID,NULL);
	return 0;
}

在这里插入图片描述

4.相关命令
ipcs 可以查看ipc对象
ipcrm 可以删除ipc对象

ntf(“mtype:%ld mtext:%s\n”,data.mtype,data.mtext);
/* 销毁消息队列 */
msgctl(msgid,IPC_RMID,NULL);
return 0;
}


[外链图片转存中...(img-tyjlFSdC-1662566629522)]

#### 4.相关命令

ipcs 可以查看ipc对象
ipcrm 可以删除ipc对象


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值