通过消息队列实现进程间通信

消息队列特点:

1.消息队列是IPC对象的一种

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

3.消息队列就是一个消息的列表。用户可以再消息队列中添加消息、读取消息等。

4.消息队列可以按照类型来发送/接受消息

 消息队列常用的四个函数 

函数作用参数属性
int msgget(key_t key, int msgflg);
 
创建消息列表

key:IPC_PRIVATE(亲缘进程)或ftok(非亲缘进程)

msgflg:IPC_CREAT | xxxx(权限,如0777)

 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
 
消息队列添加消息

msqid:消息队列id

msgp:消息结构体首地址

msgsz:消息大小

msgflg:0(发送完才返回)

  ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
 
读取消息队列消息

msqid:消息队列id

msgp:消息结构体首地址

msgsz:消息大小

msgtyp:结构体中的消息类型

msgflg:0(读完才返回)

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
 
删除消息队列

msqid:消息队列id

cmd:操作命令IPC_RMID(删除操作)、IPC_STAT(获取属性)、IPC_SET(设置操作)

buf:NULL(默认操作)

头文件:#include <sys/types.h>、   #include <sys/ipc.h>、#include <sys/msg.h>

 通过消息队列实现进程间通信

 msgget_write.c

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

#define SIZE 128
typedef struct msgbuf{
	long mtype;
	char mtext[SIZE];
}MSG;//初始化消息结构体
int main(int argc,char *argv[])
{
	key_t key = ftok(".",'a');//获取key密钥
	if(key<0)
	{
		perror("ftok");
		return -1;
	}

	int msgid = msgget(key,IPC_CREAT | 0777);//创建消息队列
	if(msgid <0 )
	{
		perror("msgget");
		return -1;
	}
	printf("msgid:%d\n",msgid);
	
	MSG msg1,msg2,msg3;
	msg1.mtype = 1;//消息类型
	strcpy(msg1.mtext,"msg1");//数据拷贝到结构体数组中

	msg2.mtype =2;
	strcpy(msg2.mtext,"msg2");

	msg3.mtype =3;
	strcpy(msg3.mtext,"msg3");

	if(msgsnd(msgid,&msg1,sizeof(MSG)-sizeof(long),0) < 0)//添加消息到列表里
	{
		perror("msgsnd");
		return -1;
	}

	if(msgsnd(msgid,&msg2,sizeof(MSG)-sizeof(long),0) < 0)
	{
		perror("msgsnd");
		return -1;
	}

	if(msgsnd(msgid,&msg3,sizeof(MSG)-sizeof(long),0) < 0)
	{
		perror("msgsnd");
		return -1;
	}
	return 0;
}

 msgget_read.c

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

#define SIZE 128
typedef struct msgbuf{
	long mtype;
	char mtext[SIZE];
}MSG;
int main(int argc,char *argv[])
{
	key_t key = ftok(".",'a');
	if(key<0)
	{
		perror("ftok");
		return -1;
	}

	int msgid = msgget(key,IPC_CREAT | 0777);
	if(msgid <0 )
	{
		perror("msgget");
		return -1;
	}
	printf("msgid:%d\n",msgid);
	
	MSG msg1,msg2,msg3;

	if(msgrcv(msgid,&msg1,sizeof(MSG)-sizeof(long),2,0) == -1)//读消息队列里的内容
	{
		perror("msgsnd");
		return -1;
	}
	printf("%s\n",msg1.mtext);


	if(msgctl(msgid,IPC_RMID,NULL) == -1)//删除消息队列
	{
		perror("msgctl");
		return -1;

	}

	return 0;
}

 注意:

      在两个.c文件中的ftok()函数中的参数要相同,不然创建的key密钥不同使得两个进程无法通信,它是两个进程能通信的关键。(    key_t key = ftok(".",'a');   )

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值