Linux多进程间通信——管道通信实现

本文介绍了Linux系统中多进程间通信的管道(Pipe)方法,包括无名管道和有名管道的使用。无名管道适用于父子进程间通信,有名管道则允许无关进程间通信。通过API函数如`pipe()`和`mkfifo()`创建管道,并通过`read()`和`write()`进行数据传输。文中提供了详细代码示例,展示了如何在C语言中实现管道通信的写进程和读进程。

Linux多进程间通信——管道通信实现

之前分享了linux多进程间通信的两种方法,套接字和共享内存通信。今天来分享一下另外一种多进程通信方法——管道。

管道分为有名管道和无名管道。无名管道用于有亲缘关系之间的进程,即父子进程之间。有名管道允许没有亲属关系的进程间使用。管道是连接读写进程的一个共享文件,允许进程以先进先出的方式写入和读出数据,发送进程以字符流的形式吧大量数据写入管道尾部,接收进程从管道头部接收数据。管道应互斥使用,大小在定义时就固定下来了,之后不能改变。

无名管道:下面先介绍一下创建无名管道的API

int fds[2];//这里定义管道的文件描述符,其中一个用于读,一个用于写
pipe(fds);//无名管道的创建接口

创建成功之后,fds[0]就相当于管道头部,用于读,fds[1]相当于管道尾部,用于写进程写入数据。

有名管道:下面再介绍一下创建有名管道的API,有名管道的创建与共享内存、消息队列的创建过程都是差不多的,我们都要标记我们创建的I管道,依此来让两个进程能在内存中识别用于通信的管道是哪一个。

//写进程
define FIFO "myfifo"//这里的宏定义就是定义一个管道标识,表明我们创建的管道叫“myfifo”
mkfifo(FIFO, 0666);//mkfifo就是管道创建API,这里名字叫“myfifo”的FIFO管道就创建成功了
fd = open(FIFO, O_WRONLY);//以只写方式打开管道
write(fd, buf, sizeof(buf));
//读进程,前面都一样
define FIFO "myfifo"//这样两个进程就能识别了
mkfifo(FIFO, 0666);
fd = open(FIFO, O_RDONLY);
read(fd, buf, sizeof(buf));

下面我就给出使用有名管道实现的多进程通信的代码:

写进程:

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

#define FIFO "myfifo" //创建一个管道通信的键值
#define BUFFER_SIZE 1024

int main(int argc, char* argv[]){
	char buf[BUFFER_SIZE];
	int real_write;
	int fd;
	int rw = 1;
	//FIFO是否存在,不存在则创建
	if(access(FIFO, F_OK) == -1){
		if(mkfifo(FIFO, 0666) < 0 && errno != EEXIST){
			printf("falied");
			exit(1);
		}
	}
	
	if((fd = open(FIFO, O_WRONLY)) == -1){
		printf("open failed\n");
		exit(1);
	}
	
	do{
		printf("请输入要写入管道的内容:\n");
		fgets(buf, BUFFER_SIZE, stdin);
		if((real_write = write(fd, buf, BUFFER_SIZE)) > 0){
			printf("第%d次写入管道:%s\n",rw++, buf);
		}
	}
	while(strlen(buf) != 0);
	close(fd);
	exit(0);
}

读进程:

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

#define FIFO "myfifo" //创建一个管道通信的键值
#define BUFFER_SIZE 1024

int main(int argc, char* agrv[]){
	char buff[BUFFER_SIZE];
	int real_read;
	int fd;
	int rc = 1;
	
	//如果FIFO已经存在则直接往下执行,不存在则创建
	if(access(FIFO, F_OK) == -1){
		if(mkfifo(FIFO, 0666) < 0 && errno != EEXIST){//创建一个管道
			printf("mkfifo failed\n");
			exit(1);
		}
	}
	//打开管道
	if((fd = open(FIFO, O_RDONLY)) == -1){
		printf("open failed\n");
		exit(1);
	}
	
	while(1){
		memset(buff, 0, BUFFER_SIZE);
		if((real_read = read(fd, buff, BUFFER_SIZE)) > 0){
			printf("第%d次读取管道:%s\n", rc++, buff);
		}
	}
	close(fd);
	exit(0);
}

读进程和写进程基本上一样的,只是在读写的一点区别。

下面展示一下效果,我在Ubuntu中编译之后运行:

image-20220624165705447
我是河边小乌龟爬,学习嵌入式软件开发路上的一名小学生,欢迎大家相互交流哇。更多内容关注公众号:河边小乌龟爬。

团队提供丰富嵌入式项目学习,以及嵌入式方向毕业设计指导,欢迎咨询。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

河边小乌龟爬

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

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

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

打赏作者

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

抵扣说明:

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

余额充值