有名管道——进程间通信

要求AB进程做通信

  1. A进程发送一句话,B进程接收打印

  2. 然后B进程发送给A进程一句话,A进程接收打印

  3. AB进程能够随时收发数据(附加题)

我采用的方法是,在AB进程内分别创建一个子进程用 以发送信号到隔壁进程。

首先分别在A进程与B进程内创建两个有名管道fifo1与fifo2

//进程A

	//创建 1 号管道
	if( mkfifo("./fifo_1",  0755) < 0 )
	{
		if(errno != 17)
		{
			perror("mkfifo");
			return -1;
		}
	}

/*****************分属于两个.c文件****************/
//进程B

//创建 2 号管道
	if( mkfifo("./fifo_2",  0755) < 0 )
	{
		if(errno != 17)
		{
			perror("mkfifo");
			return -1;
		}
	}

在进程A中只读打开管道1,只写打开管道2

在进程B中只写打开管道1,只读打开管道2

//只读打开1号管道
	int fd_1 = open("./fifo_1", O_RDONLY);
	//只写打开2号管道
	int fd_2 = open("./fifo_2", O_WRONLY);
	char str[128] = "";

//只写打开1号管道
	int fd_1 = open("./fifo_1", O_WRONLY);
	//只读打开2号管道
	int fd_2 = open("./fifo_2", O_RDONLY);
	char str[128] = "";

因为A、B进程代码几乎是镜像的,故,之后只展示进程A的代码

先是一个处理读的夫进程

//创建处理读的子进程
	pid_t pid = fork();

	if(pid 》 0)
	{
		while(1)
		{
		
			//读取进程B输入的信息
			bzero(str, sizeof(str));   //清空数组
			
			ssize_t res = read(fd_1, str, sizeof(str)-1);
			if(strcasecmp(str, "quit\n") == 0)//收到退出信号,因为read进来的信息自带一个\n 
			{
				printf("系统退出\n");
				write(fd_2, str, strlen(str));   
                kill(0, SIGKILL);               //杀死子进程
				exit(0);                        //产物
			}
			
			fprintf(stderr,"\n收到的来自B的信息为:%s",str);
			//为了美观性,增加这行代码,否则接受信息后,会变成在空白出输入信息
			fprintf(stderr,"请输入信息>>>");
		}
	}

子进程则负责发送信号到隔壁进程

else if(pid > 0)
	{
		while(1)
		{
		
			//输出信息给进程B
			fprintf(stderr,"请输入信息>>>");
			bzero(str, sizeof(str));  //清空数组
			fgets(str, sizeof(str)-1, stdin);  //读取终端的输入信息
			if(strsacecmp(str, "quit\n") == 0) //收到退出信号,采用strcasecmp无视大小写
			{
				write(fd_2, str, strlen(str));	
				break;
			}
			write(fd_2, str, strlen(str));       //向进程B传递信息	
		}

		wait(NULL);         //为子进程收尸
		close(fd_1);       //关闭管道
		close(fd_2);
	}

以下是进程A全部代码

#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/wait.h>
#include<stdlib.h>

//进程A
int main(int argc, const char *argv[])
{
	//创建 1 号管道
	if( mkfifo("./fifo_1",  0755) < 0 )
	{
		if(errno != 17)
		{
			perror("mkfifo");
			return -1;
		}
	}

	printf("一号管道创建成功\n");
	//只读打开1号管道
	int fd_1 = open("./fifo_1", O_RDONLY);
	//只写打开2号管道
	int fd_2 = open("./fifo_2", O_WRONLY);
	char str[128] = "";
	
	
	//创建处理读的父进程
	pid_t pid = fork();

	if(pid 》 0)
	{
		while(1)
		{
		
			//读取进程B输入的信息
			bzero(str, sizeof(str));   //清空数组
			
			ssize_t res = read(fd_1, str, sizeof(str)-1);
			if(strcasecmp(str, "quit\n") == 0)  //收到退出信号
			{
				printf("系统退出\n");
				write(fd_2, str, strlen(str));   //通知进程B的接收端
			    kill(0, SIGKILL);                //杀死子进程
				exit(0);
			}
			
			fprintf(stderr,"\n收到的来自B的信息为:%s",str);
			//为了美观性,增加这行代码,否则接受信息后,会变成在空白出输入信息
			fprintf(stderr,"请输入信息>>>");
		}
	}
	else if(pid > 0)
	{
		while(1)
		{
		
			//输出信息给进程B
			fprintf(stderr,"请输入信息>>>");
			bzero(str, sizeof(str));  //清空数组
			fgets(str, sizeof(str)-1, stdin);  //读取终端的输入信息
			if(strcasecmp(str, "quit\n") == 0)  //收到退出信号
			{
				write(fd_2, str, strlen(str));	
				break;
			}
			write(fd_2, str, strlen(str));			
		}

	}
	else
	{
		perror("fork");
		return -1;
	}
	return 0;
}

当任意一端输入quit时(不区分大小写,由strcasecmp实现),两边进程都会退出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老K殿下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值