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、思维导图

相关推荐
RainbowSea14 小时前
12. LangChain4j + 向量数据库操作详细说明
java·langchain·ai编程
RainbowSea14 小时前
11. LangChain4j + Tools(Function Calling)的使用详细说明
java·langchain·ai编程
考虑考虑18 小时前
Jpa使用union all
java·spring boot·后端
用户37215742613518 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊19 小时前
Java学习第22天 - 云原生与容器化
java
佛祖让我来巡山20 小时前
深入理解JVM内存分配机制:大对象处理、年龄判定与空间担保
jvm·内存分配·大对象处理·空间担保·年龄判定
聚客AI20 小时前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
渣哥21 小时前
原来 Java 里线程安全集合有这么多种
java
间彧21 小时前
Spring Boot集成Spring Security完整指南
java
间彧21 小时前
Spring Secutiy基本原理及工作流程
java