10.21 IO进程直接的通信

1、用消息队列实现两个进程直接的通信

cpp 复制代码
先输入的代码
#include<myhead.h>
//定义消息列队的结构体
struct msgbuf
{
	long mtype;  //消息类型
	char mtext[1024];  //消息正文
};

//宏定义正文的大小
#define MSGSZ (sizeof(struct msgbuf) - sizeof(long))

//定义回收僵尸信号
void handler(int signo)
{
	//判断是否为SIGCHLD信号
	if(signo == SIGCHLD)
	{
		while(waitpid(-1 , NULL ,WNOHANG)>0);
	}
}

int main(int argc, const char *argv[])
{
	//11、当进程结束时进行回收将SIGCHLD信号非阻塞回收僵尸进程
	if(signal(SIGCHLD,handler)== SIG_ERR)
	{
		perror("signal error");
		return -1;
	}
	
	//1、首先创建一个key值
	key_t key = ftok("/",'k');
	if(key == -1)
	{
		perror("ftok error");
		return -1;
	}
	printf("key = %#x\n", key);

	//2、创建消息队列
	int msqid = msgget(key , IPC_CREAT|0664);
	if(msqid == -1)
	{
		perror("msgger error");
		return -1;
	}
	//11、创建子进程
	pid_t pid = -1;
	pid = fork();

	if(pid > 0 )  //判断父进程 
	{
		//3、向消息队列中存放数据
		struct msgbuf buf1;
		while(1)
		{
			printf("请输入消息类型>>>");
			scanf("%ld",&buf1.mtype);
			getchar(); 		//吸收回车
			printf("请输入消息正文>>>");
			fgets(buf1.mtext,MSGSZ,stdin);     //从终端输入数据到正文中
			buf1.mtext[strlen(buf1.mtext)-1] = 0;      //将回车换成'\0'
	
			//将消息存入消息队列
			msgsnd(msqid,&buf1,MSGSZ,0);
			printf("发送成功\n");

			if(strcmp(buf1.mtext , "quit") == 0) //输入的是quit 就结束
			{
				break;
			}
		}
	}

	if(pid == 0)
	{
		//4、子进程读取子进程存入消息列队的数据
		struct msgbuf buf2;
		while(1)
		{
			msgrcv(msqid,&buf2,MSGSZ,0,0);   	//接收子进程中buf2中的数据
			printf("收到消息为:%s\n", buf2.mtext);
			if(strcmp(buf2.mtext,"quit") == 0)  
			{
				break;
			}
		}
		exit(EXIT_SUCCESS);
	}
	//删除消息列队
	if(msgctl(msqid,IPC_RMID,NULL)== -1)
	{
		perror("msgctl error");
		return -1;
	}


	return 0;
}
cpp 复制代码
2.后写入代码
#include<myhead.h>
//定义消息类型结构体 
struct msgbuf
{
	long mtype;  //消息类型
	char mtext[1024];  //消息正文
};
//宏定义正文大小
#define MSGSZ (sizeof(struct msgbuf) - sizeof(long))

//定义回收僵尸信号
void handler(int signo)
{
	//判断是否为SIGCHLD信号
	if(signo == SIGCHLD)
	{
		while(waitpid(-1 , NULL ,WNOHANG)>0);
	}
}


int main(int argc, const char *argv[])
{
	//11、当进程结束时进行回收将SIGCHLD信号非阻塞回收僵尸进程
	if(signal(SIGCHLD,handler) == SIG_ERR)
	{
		perror("signal error");
		return -1;
	}
	//1、创建一个key值
	key_t key = ftok("/",'k');
	if(key == -1)
	{
		perror("ftok error");
		return -1;
	}
	printf("key = %#x\n", key);
	//2、创建消息队列
	int msqid = msgget(key , IPC_CREAT|0664);
	if(msqid == -1)
	{
		perror("msgget error");
		return -1;
	}
	printf("msqid = %d\n", msqid);
	//创建子进程
	pid_t pid = -1;
	pid = fork();
	if(pid >0)  //判断父进程:
	{
		//3、父进程读取父进程中消息列队中存入的数据
		struct msgbuf buf1;
		while(1)
		{
			msgrcv(msqid,&buf1,MSGSZ,0,0);   	//接收父进程中的消息列队 buf1中的数据
			printf("收到消息为:%s\n",buf1.mtext);
			if(strcmp(buf1.mtext,"quit") == 0)    //当接收到quit 时结束程序 
			{
				break;
			}
		}
	}
	if(pid == 0)  //子进程向消息列队中存放数据
	{
		struct msgbuf buf2;
		while(1)
		{
			printf("请输入消息类型>>>");
			scanf("%ld",&buf2.mtype);  //将终端输入的数据类型写入数据类型中
			getchar();   //吸收回车
			printf("请输入消息正文>>>");
			fgets(buf2.mtext,MSGSZ,stdin);   //从终端输入数据写入到正文
			buf2.mtext[strlen(buf2.mtext)-1] = 0;  //将回车换成'\0'

			msgsnd(msqid,&buf2,MSGSZ,0);
			printf("发送成功\n");
			if(strcmp(buf2.mtext,"quit") == 0)
			{
				break;
			}

		}
		exit(EXIT_SUCCESS);
	}

	//4、删除消息列队
	if(msgctl(msqid,IPC_RMID,NULL) == -1)
	{
		perror("msgctl error");
		return -1;
	}
	return 0;
}

2、思维导图

相关推荐
云烟成雨TD1 分钟前
Agent Scope Java 2.x 系列【6】消息层
java·人工智能·agent
云烟成雨TD2 分钟前
Spring AI Alibaba 1.x 系列【74】Agentic RAG 与混合 RAG
java·人工智能·spring
小刘|4 分钟前
Spring AI 结构化输出 + 大模型参数全解(含千问调优)
java·后端·spring
云烟成雨TD5 分钟前
Spring AI Alibaba 1.x 系列【79】图执行生命周期的可观测性基础设施
java·人工智能·spring
霸道流氓气质9 分钟前
Java 单元测试生成大量 Excel 测试数据实战指南
java·单元测试·excel
MicroTech20259 分钟前
量子隐形传态路线的瓶颈与突破,微算法科技(MLGO)以技术创新助力量子通信长距离组网
科技·算法·量子计算
洛水水9 分钟前
【力扣100题】89.下一个排列
数据结构·算法·leetcode
洛水水10 分钟前
【力扣100题】90.寻找重复数
算法·leetcode·职场和发展
io无心14 分钟前
基于Image 2的多配件商品图生成技术实现(已开源)
java·image2
鱼子星_16 分钟前
【数据结构】排序的拓展——快速排序的生态多样性与归并排序沾染文件操作
c语言·数据结构·算法