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

相关推荐
427724001 小时前
IDEA使用git不提示账号密码登录,而是输入token问题解决
java·git·intellij-idea
chengooooooo1 小时前
苍穹外卖day8 地址上传 用户下单 订单支付
java·服务器·数据库
李长渊哦1 小时前
常用的 JVM 参数:配置与优化指南
java·jvm
计算机小白一个1 小时前
蓝桥杯 Java B 组之设计 LRU 缓存
java·算法·蓝桥杯
万事可爱^2 小时前
HDBSCAN:密度自适应的层次聚类算法解析与实践
算法·机器学习·数据挖掘·聚类·hdbscan
大数据追光猿4 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!4 小时前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
夏末秋也凉4 小时前
力扣-回溯-46 全排列
数据结构·算法·leetcode
南宫生4 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
柠石榴4 小时前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯