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

相关推荐
爱吃山竹的大肚肚4 分钟前
Nginx 最核心和常用的命令
java·运维·服务器·前端·nginx
进阶小白猿6 分钟前
Java技术八股Day19
java·开发语言
派大鑫wink8 分钟前
【Day33】Servlet 基础:生命周期、Request/Response 对象实战
java·servlet
沛沛老爹8 分钟前
Web开发者进阶AI架构:Agent Skills与MCP的企业级架构权衡实战
java·人工智能·架构·llm·llama·rag
二哈喇子!10 分钟前
SpringBoot启动失败Application run failed的解决办法
java·spring boot·mybatis
J2虾虾10 分钟前
springboot 的 WebMvcConfigurer
java·spring boot·后端
jghhh0112 分钟前
三维热传导方程和泊松方程的有限元方法MATLAB实现
开发语言·算法·matlab
阿杰 AJie13 分钟前
Jackson 常用注解与完整用法总结
java
阿崽meitoufa14 分钟前
JVM虚拟机:HotSpot虚拟机对象
jvm
二哈喇子!20 分钟前
IDEA启动后控制台不报错,但是页面访问404
java·intellij-idea·mybatis