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

相关推荐
努力搬砖的程序媛儿1 小时前
uniapp悬浮可拖拽按钮
java·前端·uni-app
上海拔俗网络1 小时前
“AI开放式目标检测系统:开启智能识别新时代
java·团队开发
Leaf吧1 小时前
springboot 配置多数据源以及动态切换数据源
java·数据库·spring boot·后端
java1234_小锋2 小时前
Java中如何安全地停止线程?
java·开发语言
siy23332 小时前
[c语言日寄]结构体的使用及其拓展
c语言·开发语言·笔记·学习·算法
栗子~~2 小时前
基于quartz,刷新定时器的cron表达式
java
吴秋霖2 小时前
最新百应abogus纯算还原流程分析
算法·abogus
杨过姑父2 小时前
Servlet3 简单测试
java·servlet
chengxuyuan666662 小时前
python基础语句整理
java·windows·python
一只会飞的猪_2 小时前
国密加密golang加密,java解密
java·开发语言·golang