linux 采用消息队列和共享内存实现通信

定义一个学生结构体

创建一个A工程通过共享内存技术,共享内存可放置N个学生结构体(共享内存大小为sizeof(学生结构体)*N)

A工程运行,可接受控制台输入学生学号、姓名,控制台输入以后,将结构体数据写入共享内存,共享内存操作完成后发出一个消息队列的消息,消息里的数据是写入的共享内存数据块的下标序号(下标序号也可以通过控制台手动输入)

创建一个B工程在不断接收消息队列的消息

B工程收到消息后,根据接收的消息中的下标,从共享内存中读出1个学生结构体,打印控制台,并清空共享内存对应的位置

工程1的代码

#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/shm.h>
using namespace std;

typedef struct messagebuf {
	long mtype;       /* message type, must be > 0  必须大于0 */
	char mtext[4];    /* message data */ //消息的数据 自己定义字节数
}MSGBUF;
//定义一个学生结构体,包含学号与姓名
typedef struct  student
{
	char stuID[20];
	char stuName[20];
}STU;
int main()
{
	//定义数值用于当做共享内存的下标做发送发送
	int n = 0;
	n = 10;
	//定义一个消息队列
	int msgid = msgget((key_t)1001, IPC_CREAT | 0777);
	//当msgid小于0时创建失败
	if (msgid < 0)
	{
		perror("msgid error");
	}
	cout << "msgid = " << msgid << endl;
	//准备数值先赋初值为0
	MSGBUF buf = { 0 };
	//给学生结构体赋初值为0
	STU stu = { 0 };
	//定义一个void*类型的数据用于保存共享内存的首地址
	void* shmaddr;
	//创建一个共享内存
	int shmid = shmget((key_t)1002, sizeof(STU) * n, IPC_CREAT | 0777);
	//当shmid等于-1时,创建共享内存失败返回出1,程序结束
	if (shmid == -1)
	{
		perror("shmget error");
		return 1;
	}
	else  //数据链接
	{
		//链接
		cout << "shmid = " << shmid << endl;
		//指向共享内存的首地址
		shmaddr = shmat(shmid, NULL, 0);
		//有n段就链接n段
		for (int i = 0; i < n; i++)
		{
			sprintf(stu.stuID, "OMO2309%d", i);
			sprintf(stu.stuName, "张三%d", i);
			//数据的操作  数据写到共享内存
			//		目标:共享内存	 源头		长度
			//void *memcpy(void *dest, const void *src, size_t n);
			//将STU结构体数据写到共享内存中
			memcpy((void*)(shmaddr + sizeof(STU) * i), &stu, sizeof(stu));
			cout << "拷贝数据成功 " << endl;
		}
	}
	//--------------------数据传输----------------------------
	//用于手动输入下标
	int num = 0;
	//消息队列的类型绑定
	buf.mtype = 1;
	while (1)
	{
		cout << "选择传输的数据,请输入1-10的数:" << endl;
		cin >> num;
		if (num > n || num < 0)
		{
			cout << "输入输数值不在范围类" << endl;
			return -1;
		}
		//将int类型的数据转换为char*
		sprintf(buf.mtext, "%d", num);
		if (msgsnd(msgid, &buf, sizeof(buf.mtext), 0) == -1)
		{
			perror("msgsnd error");
		}
		else
		{
			cout << "消息队列发送成功!!" << endl;
		}
		//发送完数据后,共享内存中被读取走了
		//为了保证下一次还有数据可以读取所以需要进行补充
		sprintf(stu.stuID, "OMO2309%d", num);
		sprintf(stu.stuName, "张三%d", num);
		memcpy((void*)(shmaddr + sizeof(STU) * num), &stu, sizeof(stu));
		cout << "数据补充成功 " << endl;
		sleep(1);
	}
	shmdt(shmaddr);
	cout << "共享内存断开 " << endl;
	return 0;
}

工程2的代码:

#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/shm.h>
#include <stdlib.h>
using namespace std;

typedef struct messagebuf {
	long mtype;       /* message type, must be > 0  必须大于0 */
	char mtext[4];    /* message data */ //消息的数据 自己定义字节数
}MSGBUF;
//定义一个学生结构体,包含学号与姓名
typedef struct  student
{
	char stuID[20];
	char stuName[20];
}STU;
int main()
{
	//定义数值用于当做共享内存的下标做发送发送
	int n = 0;
	n = 10;
	//定义一个消息队列
	int msgid = msgget((key_t)1001, IPC_CREAT | 0777);
	//当msgid小于0时创建失败
	if (msgid < 0)
	{
		perror("msgid error");
	}
	cout << "msgid = " << msgid << endl;
	//准备数值先赋初值为0
	MSGBUF buf = { 0 };
	//给学生结构体赋初值为0
	STU resstu = { 0 };
	//定义一个void*类型的数据用于保存共享内存的首地址
	void* shmaddr;
	//创建一个共享内存
	int shmid = shmget((key_t)1002, sizeof(STU) * n, IPC_CREAT | 0777);
	//当shmid等于-1时,创建共享内存失败返回出1,程序结束
	if (shmid == -1)
	{
		perror("shmget error");
		return 1;
	}
	else  //数据链接
	{
		//链接
		cout << "shmid = " << shmid << endl;
		//指向共享内存的首地址
		shmaddr = shmat(shmid, NULL, 0);
	}
	//--------------------数据传输----------------------------
	//接受输入的下标
	int num = 0;
	//消息队列的类型绑定
	buf.mtype = 1;
	while (1)
	{
		if (msgrcv(msgid, &buf, sizeof(buf.mtext), 1, 0) == -1)
		{
			perror("msgrcv error");
		}
		else
		{
			//打印一下接收到的数据信息
			cout << "接收到的数据:" << buf.mtext << endl;
			//将数据赋值给num方便后面的操作
			num = atoi(buf.mtext);
			bzero(&buf, sizeof(buf));

			memcpy(&resstu, (void*)(shmaddr + sizeof(STU) * num), sizeof(STU));
			cout << "读取数据成功 " << resstu.stuID << " " << resstu.stuName << endl;
			//利用内存初始化做清空
			memset((void*)(shmaddr + sizeof(STU) * num), 0, sizeof(STU));
		}
	}
	shmdt(shmaddr);
	cout << "共享内存断开 " << endl;
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值