百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Linux进程间通信——管道

bigegpt 2024-08-28 12:27 1 浏览

管道

  • 什么是管道?
    一个进程连接到另一个进程的一个数据流称为一个“管道”。

匿名管道pipe

  • 用于父子间的通信
  • 管道最大64K,由环形队列组成
  • 需要占用两个文件描述符,分别作为管道读端、写端
  • 管道是半双工的,需要确定通信方向
    父写子读,关闭父读、子写
    子写父读,关闭子读、父写
  • 优点:稳定、经典

pipe函数原型

头文件:<unistd.h>

int pipe(int file_descriptor[2]);

功 能:创建一无名管道
参 数:file_descriptor:文件描述符数组,其中file_descriptor[0]表示读端,file_descriptor[1]表示写端
返回值:成功返回0,失败返回-1

开辟了管道之后如何实现两个进程间的通信呢?比如可以按下面的步骤通信。


1、父进程调用pipe开辟管道,得到两个文件描述符指向管道的两端。
2、父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。
3、父进程关闭管道读端,子进程关闭管道写端。父进程可以往管道里写,子进程可以从
4、管道里读,管道是用环形队列实现的,数据从写端流入从读端流出,这样就实现了进程间通信。

#include <stdlib.h>
#include <unistd.h>

#define MAXLINE 80

int main(void)
{
	int n;
	int fd[2];
	pid_t pid;
	char line[MAXLINE];

	if (pipe(fd) < 0) 
	{
		perror("pipe");
		exit(1);
	}
	if ((pid = fork()) < 0) 
	{
		perror("fork");
		exit(1);
	}
	if (pid > 0) // 父进程 
	{ 
		close(fd[0]);//关闭读端
		write(fd[1], "hello world\n", 12);
		wait(NULL);
	}
	else  //子进程
	{
		close(fd[1]);//关闭写端
		n = read(fd[0], line, MAXLINE);
		write(STDOUT_FILENO, line, n);
	}
	return 0;
}

运行结果

注意事项

  • 如果试图从管道写端读取数据,或者向管道读端写入数据都将导致错误发生
  • 写端未写完,写端暂时无数据,读端再次去读,read发生阻塞(读太快)
  • 读端未读完,写端满了,写端再次写,write发生阻塞(写太快)
  • 读端关闭,写端写数据,产生SIGPIPE信号,默认会终止进程
  • 写端关闭,当数据读完,再次读返回0

Linuxc/c++服务器开发高阶视频,电子书学习资料后台私信【架构】获取

有名管道fifo

pipe是有血缘关系进程之间的通信,那么当没有血缘关系的进程想要通信怎么办?

  • 创建一个有名管道fifo(也叫做named pipe),解决无血缘关系的进程通信
  • fifo是一个设备文件,本身无大小,在文件系统中以文件名的形式存在,因此即使进程与创建fifo的进程不存在血缘关系也依然可以通信,前提是可以访问该路径。
  • fifo总是遵循先进先出的原则,即第一个进来的数据会第一个被读走

与匿名管道pipe的区别

  • 提供了一个路径名与之关联,以fifo文件的形式存储于文件系统中,能够实现任何两个进程之间通信。而匿名管道对于文件系统是不可见的,它仅限于在父子进程之间的通信。 但是fifo底层是由pipe实现的。

如何创建fifo?

  • 命令行上创建
  • 程序内创建
    头文件:
    #include <sys/types.h>
    #include <sys/stat.h>
    函数原型:
    int mkfifo(const char *pathname, mode_t mode);

做个测试,分别写两个程序,一个写,一个读
写进程

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

int main(int argc, char* argv[])
{
	int fd;
	char buff[1024] = "hello world\n";

	if (argc < 2)
	{
		printf("enter you fifoname\n");
		exit(1);
	}
	fd = open(argv[1], O_WRONLY);//只写方式打开

	if (fd < 0)
	{
		perror("open\n");
	}

	write(fd, buff, strlen(buff));//写入hello world
	close(fd);

	return 0;
}

读进程

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

int main(int argc, char* argv[])
{
	int fd;
	int len;
	char buff[1024] = "hello world\n";

	if (argc < 2)
	{
		printf("enter you fifoname\n");
		exit(1);
	}
	fd = open(argv[1], O_RDONLY);//只写方式打开

	if (fd < 0)
	{
		perror("open\n");
	}

	len = read(fd, buff, sizeof(buff));
	write(STDOUT_FILENO, buff, len);
	close(fd);

	return 0;
}

测试结果如下


首先myfifo是我们提前创建好的fifo管道文件,然后执行写进程,再执行读进程。读到了hello world,执行前后myfifo文件大小都为0

注意事项

  • 当只写打开FIFO管道时,如果没有FIFO没有读端打开,则open写打开会阻塞。
  • FIFO内核实现时可以支持双向通信(pipe单向通信,因为父子进程共享同一个file结构体)
  • FIFO可以一个读端,多个写端;也可以一个写端,多个读端。

相关推荐

得物可观测平台架构升级:基于GreptimeDB的全新监控体系实践

一、摘要在前端可观测分析场景中,需要实时观测并处理多地、多环境的运行情况,以保障Web应用和移动端的可用性与性能。传统方案往往依赖代理Agent→消息队列→流计算引擎→OLAP存储...

warm-flow新春版:网关直连和流程图重构

本期主要解决了网关直连和流程图重构,可以自此之后可支持各种复杂的网关混合、多网关直连使用。-新增Ruoyi-Vue-Plus优秀开源集成案例更新日志[feat]导入、导出和保存等新增json格式支持...

扣子空间体验报告

在数字化时代,智能工具的应用正不断拓展到我们工作和生活的各个角落。从任务规划到项目执行,再到任务管理,作者深入探讨了这款工具在不同场景下的表现和潜力。通过具体的应用实例,文章展示了扣子空间如何帮助用户...

spider-flow:开源的可视化方式定义爬虫方案

spider-flow简介spider-flow是一个爬虫平台,以可视化推拽方式定义爬取流程,无需代码即可实现一个爬虫服务。spider-flow特性支持css选择器、正则提取支持JSON/XML格式...

solon-flow 你好世界!

solon-flow是一个基础级的流处理引擎(可用于业务规则、决策处理、计算编排、流程审批等......)。提供有“开放式”驱动定制支持,像jdbc有mysql或pgsql等驱动,可...

新一代开源爬虫平台:SpiderFlow

SpiderFlow:新一代爬虫平台,以图形化方式定义爬虫流程,不写代码即可完成爬虫。-精选真开源,释放新价值。概览Spider-Flow是一个开源的、面向所有用户的Web端爬虫构建平台,它使用Ja...

通过 SQL 训练机器学习模型的引擎

关注薪资待遇的同学应该知道,机器学习相关的岗位工资普遍偏高啊。同时随着各种通用机器学习框架的出现,机器学习的门槛也在逐渐降低,训练一个简单的机器学习模型变得不那么难。但是不得不承认对于一些数据相关的工...

鼠须管输入法rime for Mac

鼠须管输入法forMac是一款十分新颖的跨平台输入法软件,全名是中州韵输入法引擎,鼠须管输入法mac版不仅仅是一个输入法,而是一个输入法算法框架。Rime的基础架构十分精良,一套算法支持了拼音、...

Go语言 1.20 版本正式发布:新版详细介绍

Go1.20简介最新的Go版本1.20在Go1.19发布六个月后发布。它的大部分更改都在工具链、运行时和库的实现中。一如既往,该版本保持了Go1的兼容性承诺。我们期望几乎所...

iOS 10平台SpriteKit新特性之Tile Maps(上)

简介苹果公司在WWDC2016大会上向人们展示了一大批新的好东西。其中之一就是SpriteKitTileEditor。这款工具易于上手,而且看起来速度特别快。在本教程中,你将了解关于TileE...

程序员简历例句—范例Java、Python、C++模板

个人简介通用简介:有良好的代码风格,通过添加注释提高代码可读性,注重代码质量,研读过XXX,XXX等多个开源项目源码从而学习增强代码的健壮性与扩展性。具备良好的代码编程习惯及文档编写能力,参与多个高...

Telerik UI for iOS Q3 2015正式发布

近日,TelerikUIforiOS正式发布了Q32015。新版本新增对XCode7、Swift2.0和iOS9的支持,同时还新增了对数轴、不连续的日期时间轴等;改进TKDataPoin...

ios使用ijkplayer+nginx进行视频直播

上两节,我们讲到使用nginx和ngixn的rtmp模块搭建直播的服务器,接着我们讲解了在Android使用ijkplayer来作为我们的视频直播播放器,整个过程中,需要注意的就是ijlplayer编...

IOS技术分享|iOS快速生成开发文档(一)

前言对于开发人员而言,文档的作用不言而喻。文档不仅可以提高软件开发效率,还能便于以后的软件开发、使用和维护。本文主要讲述Objective-C快速生成开发文档工具appledoc。简介apple...

macOS下配置VS Code C++开发环境

本文介绍在苹果macOS操作系统下,配置VisualStudioCode的C/C++开发环境的过程,本环境使用Clang/LLVM编译器和调试器。一、前置条件本文默认前置条件是,您的开发设备已...