0
点赞
收藏
分享

微信扫一扫

Linux——进程间通信(消息队列)

大明宫 2022-03-11 阅读 112
linux

消息队列

管道和共享内存:字节流数据
消息:数据报(类型+数据)
队列:优先级队列
可以指定类型来读取,在相同类型下,按照先进先出的顺序
在这里插入图片描述
消息队列的操作:

1.创建和访问一个消息队列
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflag);
  • key:某个消息队列的名字,给一个整型值即可
  • msgflag:有两个选项IPC_CREAT和IPC_EXCL,单独使用IPC_CREAT,如果消息队列不存在则创建之,如果存在则打开返回;单独使用IPC_EXCL是没有意义的;两个同时使用,如果消息队列不存在则创建之,如果存在则出错返回。
  • 返回值成功返回一个非负整数,即消息队列的标识码,失败返回-1
    2.把一条消息添加到消息队列中
int msgsnd(int msqid, const void *msqp, size_t msqsz, int msqflg);
  • msgid:由msgget函数返回的消息队列标识码
  • msqp:指针指向准备发送的消息
  • msqsz:消息结构中数据部分的大小,不包括类型大小
  • msgflg:默认为0
  • 返回值:成功返回0,失败返回-1

消息结构一方面必须小于系统规定的上限,另一方面必须以一个long int长整型开始,接受者以此来确定消息的类型

struct msgbuf 
{
	long mtye;    //消息类型,必须大于0
	char mtext[1]; //消息数据
}; 

3.从一个消息队列接受消息

ssize_t msgrcv(int msqid, void *msqp, size_t msqsz, long msqtyp, int msqflg);

参数:与msgsnd相同
返回值:成功返回实际放到接收缓冲区里去的字符个数,失败返回-1
如果指定的空间不能将消息的数据完全存储下来,则本次读取不成功

4.消息队列的控制函数

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
  • msqid:由msgget函数返回的消息队列标识码
  • cmd:有三个可选的值
  • 返回值:成功返回0,失败返回-1

和之前一样,我们写两个程序,a向消息队列中写入数据,b从消息队列中读取数据。
在这里插入图片描述

在这里插入图片描述
完成下面的操作:

注意:在接收消息的时候,如果将消息类型改为0,不代表接收0号消息,而是不区分消息类型,直接接收,最后靠接受者自己使用

msg.h

#program once
typedef struct msgbuf
{
	long mtype;
	char mtext[128];
}MsgBuf;

发送

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<unistd.h>

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

#include"msg.h"

int main(int argc,char *argv[])
{
	//argv[1]:type
	//argv[2]:data
	if(argc < 3)
	{
		printf("Please input type and data\n");
		exit(0);
	}
	
	MsgBuf mess;
	memset(&mess,0,sizeof(mess));
	sscanf(argv[1],"%d",&mss.mtype);
	strcpy(msss.mtext,argv[2]);
	
	int msgid = msgget((key_t)1234,IPC_CREAT | 0664);
	assert(msgid != -1);

	msgsnd(msgid,&mess,strlen(mess,mtext),0);
	
	exit(0);
}

接收(注意读取问题)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<unistd.h>

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

#include"msg.h"

int main(int argc,char *argv[])
{
	if(argc < 2)
	{
		printf("please input type\n");
		exit(0);
	}
	
	MsgBuf mess;
	memset(&mess,0,sizeof(mess));
	
	long type = 0;
	sscanf(argv[1],"%d",&type);
	
	int msgid = msgget((key_t)1234,IPC_CREAT | 0664);
	assert(msgid != -1);
	
	msgrcv(msgid,&mess,127,type,0);//改成5看看结果,消息截取
	printf("type:%d,data :%s\n",mess.mtype,mess.mtext);
	
	exit(0);
}

简单总结:
在这里插入图片描述

举报

相关推荐

0 条评论