【Linux】Linux管道揭秘:匿名管道如何连接进程世界
🌈个人主页:Yui_
🌈Linux专栏:Linux
🌈C语言笔记专栏:C语言笔记
🌈数据结构专栏:数据结构
🌈C++专栏:C++
文章目录
- 1.什么是管道 ?
- 2. 管道的类型
- 2.1 匿名管道
- 2.1.1 介绍pipe()
- 2.1.2 pipe()简单示例:父子进程通过管道通信
- 2.1.3 管道的4种情况与5种特性
- 2.1.4 匿名管道原理
- 2.1.5 用fork来共享管道的原理
- 2.1.6 站在文件描述符角度-深度理解管道
- 2.1.7 站在内核角度-管道的本质
- 3. 匿名管道总结
1.什么是管道 ?
管道(Pipe)是一种常见的进程间通信(IPC,Inter-Process Communication)机制,在 Unix/Linux 系统中尤其重要。它允许一个进程的输出直接作为另一个进程的输入,而不需要使用中间文件。管道通常用于将多个命令连接起来,让它们像流水线一样处理数据。
管道在 Unix/Linux 系统中提供了一种简便的机制,允许数据在不同进程之间传递。它提供了一个缓冲区,数据写入管道的一端(写端),然后可以从另一端(读端)读取。管道的本质是一种半双工的通信机制,即数据只能沿一个方向流动。
提问:有没有一些直观的管道的利用?
当然。其实早在Linux的指令学习中,我们就已经接触到了管道。就是这个符号|。
ubuntu@VM-20-9-ubuntu:~/pipeTest$ ls -l
total 24
-rwxrwxr-x 1 ubuntu ubuntu 16576 Nov 5 11:41 a.out
-rw-rw-r-- 1 ubuntu ubuntu 1285 Nov 5 11:40 pipeTest1.c
ubuntu@VM-20-9-ubuntu:~/pipeTest$ ls -l|grep "pipeTest1.c"
-rw-rw-r-- 1 ubuntu ubuntu 1285 Nov 5 11:40 pipeTest1.c
ubuntu@VM-20-9-ubuntu:~/pipeTest$
这就是一个管道的简单使用,我们都知道,在大部分Linux的指令都是一个可执行文件,运行起来就是一个进程。ls -l的作用就是显示当前目录文件的信息,现在我们通过|将这个显示的信息通过管道传递给grep,不就实现了两个进程间的相互通信了嘛。这就是管道的核心作用:实现进程间的通信,高效传递数据,避免了使用临时文件的麻烦.
2. 管道的类型
管道存在两种类型:
- 匿名管道,用于父子进程或者兄弟进程间的数据传递,没有名字,仅限具有亲缘关系的进程。
- 命名进程,具有文件名,可以在不相干的进程间使用。
2.1 匿名管道
匿名管道通过pipe()创建。
2.1.1 介绍pipe()
#include <unistd.h>
int pipe(int pipefd[2]);
pipefd:是一个数组,它包含两个元素,分别是管道的读端和写端的文件描述符。
pipefd[0]:读端(用于读取数据)。pipefd[1]:写端(用于写入数据)。
pipe()创建一个管道,并将两个文件描述符存储在pipefd数组中。管道的数据流是单向的:数据从写端流向读端。
关于返回值:- 成功:返回0.
- 失败:返回-1.
使用pepe()的基本流程:
- 创建管道:调用
pipe()函数。 - 使用
fork()创建一个子进程。 - 在父进程关闭写端,使用读端读取数据。
- 在子进程中关闭读端,使用写端将数据传输给父进程。
2.1.2 pipe()简单示例:父子进程通过管道通信
//本代码用来测试子进程提供匿名管道将信息传递给父进程 24/11/5
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define SIZE 1024void writer(int wfd)
{char buf[SIZE];const char* str = "hello father,i am child";int count = 1;pid_t id = getpid();while(true){//格式化输入snprintf(buf,sizeof(buf)-1,"message:%s,pid:%d,times:%d",str,id,count);write(wfd,buf,strlen(buf));count+=1;sleep(1);}
}void reader(int rfd)
{char buf[SIZE];while(true){ssize_t n = read(rfd,buf,sizeof(buf)-1);if(n == -1){perror("read");return;}printf("%s\n",buf);}}int main()
{//文件标识符int fd[2];if(pipe(fd) < 0){//errorperror("pipe error");return 1;}pid_t id = fork();if(id<0){perror("fork error");return 1;}else if(id == 0){//child//关闭读端close(fd[0]);writer(fd[1]);exit(1);}//fatherclose(fd[1]);reader(fd[0]);wait(NULL);return 0;
}
运行结果:

如此我们我们便实现了父子间的管道通信。
pipe() 是一个非常重要的系统调用,它为进程间通信提供了一个简单而高效的机制。通过管道,多个进程可以协作完成任务,并且避免了中间文件的使用。在父子进程之间的通信,或在处理大量数据时,管道通常是最常用的 IPC 方式之一。
2.1.3 管道的4种情况与5种特性
4种情况:
- 管道内部没有数据时且子进程不关闭自己的写端文件fd,读端(父)就会堵塞等待,直到pipe有数据,
- 管道内部被写满且父进程(读端)不关闭自己的fd,写端写满后,就会堵塞等待。
- 对于写端而言:不写了且关闭了pipe,读端会将pipe中的数据读完,最后就会读到返回值为0,表示读结束,类似读到了文件的结尾。
- 读端不读且关闭,写再写,OS会直接终结写入的进程(子进程)通过信号13)SIGPIPE来杀死进程。
5种特性: - 自带同步机制。
- 血缘关系进行通信,常见于父子进程。
- pipe是面向字节流的。
- 父子进程退出,管道自动释放,文件的生命周期是跟随进程的。
- 管道只能单向通信,半双工的一种特殊情况。
2.1.4 匿名管道原理
通过父子进程继承关系,再将文件描述符关闭,实现一端写,一端读就是匿名管道.
创建匿名管道的步骤:
- 父进程以读写的方式打开,文件。父进程fork创建子进程,子进程会拷贝一份PCB结构,PCB中会包含files_struct结构,files_struct中有一个指向struct file(文件)的指针数组,而文件描述符就是这个数组的下标。
- 拷贝完成后,子进程也就存在了指向
struct file的对应文件描述符。- 又因为,
struct file是独属于的文件的,和进程没有关系,也就不用拷贝,也就是说此时父子进程同时指向了一块公共区域struct file(不同进程看见同一份资源)。- write是系统调用接口,会将数据放在内核缓冲区,底层会定期刷新缓冲区将内容写入磁盘。
- 匿名管道是一个半双工的通信机制,也就是说,数据只能沿一个方向流动,为了实现半双工的通信方式,父子进程需要关闭各种不需要的文件描述符。
2.1.5 用fork来共享管道的原理
使用fork后

2.1.6 站在文件描述符角度-深度理解管道
0 1 2 分别为 标准输入,标准输出,标准错误。

2.1.7 站在内核角度-管道的本质
Linux下一切皆文件.
所以我们也应该用看待文件的眼观,去理解管道。
我们可以将管道(Pipe)理解为一种特殊类型的文件。实际上,管道确实是由操作系统内部的内存缓冲区实现的,它通过文件描述符来进行访问,就像其他普通文件一样。通过这种类比,我们可以从文件的角度理解管道。

3. 匿名管道总结
通过匿名管道,进程可以轻松地进行数据交换,而不需要借助临时文件或其他外部资源。尽管管道有一些局限性(如单向传输和缓冲区限制),它仍然是许多进程间通信场景中常见的选择。
注意:管道是半双工的,数据只能向一个方向流动,需要双方通信时,可以建立两个管道。
相关文章:
【Linux】Linux管道揭秘:匿名管道如何连接进程世界
🌈个人主页:Yui_ 🌈Linux专栏:Linux 🌈C语言笔记专栏:C语言笔记 🌈数据结构专栏:数据结构 🌈C专栏:C 文章目录 1.什么是管道 ?2. 管道的类型2.1 匿…...
【LeetCode】【算法】155. 最小栈
LeetCode 155. 最小栈 题目描述 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。 void push(int val) 将元素val推入堆栈。 void pop() 删除堆栈顶部的元素。 int …...
3.3 windows,ReactOS系统中页面的换出----1
系列文章目录 文章目录 系列文章目录3.3 页面的换出MiBalancerThread()MmTrimUserMemory()MmPageOutVirtualMemory() 3.3 页面的换出 在前一节中我们看到,如果有映射的页面已经被倒换到磁盘上即倒换文件中,…...
QCustomPlot添加自定义的图例,实现隐藏、删除功能(二)
文章目录 实现步骤:详细代码示例:实现原理和解释:使用方法:其他参考要实现一个支持复选框来控制曲线显示和隐藏的自定义 QCPLegend 类,可以通过继承 QCPLegend 并重写绘制和事件处理方法来实现,同时发出信号通知曲线的状态变更。 实现步骤: 继承 QCPLegend 类,添加绘…...
Linux云计算 |【第五阶段】CLOUD-DAY8
主要内容: 掌握DaemonSet控制器、污点策略(NoSchedule、Noexecute)、Job / CronJob资源对象、掌握Service服务、服务名解析CluterIP(服务名自动发现)、(Nodeport、Headless)、Ingress控制器 一…...
岛屿数量 广搜版BFS C#
和之前的卡码网深搜版是一道题 力扣第200题 99. 岛屿数量 题目描述 给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。…...
hive切换表底层文件类型以及分隔符
1、改底层文件存储类型,但是一般只会在数据文件与期望类型一致的时候使用,比如load等方式时发现建表时没指定对这样的,因为这个语句不会更改具体的底层文件内容,只改元数据 ALTER TABLE 表名 SET FILEFORMAT 希望类型;2、更改数据…...
ChatGPT o1与GPT-4o、Claude 3.5 Sonnet和Gemini 1.5 Pro的比较
全新的ChatGPT o1模型(代号“Strawberry”)是OpenAI的最新进展,专注于以前的AI模型难以应对的领域:高层次推理、数学和复杂编程。OpenAI设计o1模型以花费更多时间思考问题,使其在需要逐层推理的任务中提高准确性。本文…...
asp.net文件防盗链
URLRewriter实现 可以参考下面的文章 代码 .net framework 新建asp.net framework的web项目,新建AntiTheftChainHandler using System.Web;namespace AntiTheftChainStu01.Handler {public class AntiTheftChainHandler : IHttpHandler{public bool IsReusable…...
【日志】力扣58.最后一个单词的长度//14.最长公共前缀//28. 找出字符串中第一个匹配项的下标
2024.11.6 【力扣刷题】 58. 最后一个单词的长度 - 力扣(LeetCode)https://leetcode.cn/problems/length-of-last-word/?envTypestudy-plan-v2&envIdtop-interview-150 int lengthOfLastWord(char* s) {int count 0;for (int i strlen(s) - 1; i…...
华为杯”第十五届中国研究生数学建模竞赛-B题:光传送网建模与价值评估(续)
目录 4. 问题二 光传送网规划 4.1 基本假设 4.2 模型建立 4.3 子问题一 4.2 子问题二 4.5 子问题三 5. 问题三 改善星座图 5.1 问题简述 5.2 问题分析 5.3 建模与问题求解 5.3.1 方案一 5.3.2 方案二 6. 模型评价 6.1 模型的优点 6.2 模型的缺点 参考文献 本文篇幅较长,分为上…...
android 使用xml设置背景图片和圆角
使用xml设置背景图片和圆角 <?xml version"1.0" encoding"utf-8"?> <layer-list xmlns:android"http://schemas.android.com/apk/res/android"><item><shape><solid android:color"android:color/transparen…...
数据结构,问题 E: 表达式括号匹配
题目描述 假设一个表达式有英文字母(小写)和数字、运算符(,—,*,/)和左右小(圆)括号构成,以“”作为表达式的结束符。请编写一个程序检查表达式中的左右圆括号…...
国家宠物美容师职业技能等级评价(高级)理论考试题
国家宠物美容师职业技能等级评价 理论考试复习参考范围 高级/三级 宠物美容师(高级)理论考试题 一 判断题 犬只的世界只有黑白灰三种,通过颜色呈现的深浅度进行辨识(A ) A 对 B 错 美国养犬俱乐部简称AKC…...
Spring挖掘:(AOP篇)
学习AOP时,我们首先来了解一下何为AOP 一. 概念 AOP(面向切面编程,Aspect Oriented Programming)是一种编程技术,旨在通过预编译方式或运行期动态代理实现程序功能的统一管理和增强。AOP的主要目标是在不改变原有业务逻辑代码的…...
十四届蓝桥杯STEMA考试Python真题试卷第二套第四题
来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第四题:糖果罐调整 该题解通过贪心策略在每一步都选择对当前状态最有利的操作,从而达到最少调整次数的目标。 题目描述 现有 N 罐糖果,且已知每罐糖果的初始数量。现给出两个数值 L 和 R(L≤R),需要把每罐糖果的数…...
单元测试怎么做
单元测试是软件开发中非常重要的一部分,能够确保代码的正确性、可靠性和可维护性。对于 Vue 项目来说,单元测试主要关注的是测试组件及其相关功能是否正常。下面是如何在 Vue 项目中进行单元测试的详细步骤,包括测试框架的选择、测试工具的配…...
移动应用开发 实验二:标准身高计算器
文章目录 准备工作一,创建Android Studio项目二,创建活动模块三,设计用户界面(一)设置页面布局(二)添加标题文本控件(三)设计体重输入框(四)设计性…...
金华迪加现场大屏互动系统 mobile.do.php 任意文件上传漏洞复现
0x01 产品描述: 金华迪加现场大屏互动系统是由金华迪加网络科技有限公司开发的一款专注于增强活动现场互动性的系统。该系统设计用于提供高质量的现场互动体验,支持各种大型活动,如企业年会、产品发布会、展览展示等。其主要功能包…...
使用 pd.ExcelWriter 创建多工作表 Excel 文件的详细教程
with pd.ExcelWriter(...) as writer 可以将多个内容写入一个 Excel 文件中。具体地说,它创建了一个Excel 文件写入器,使得我们可以在一个文件中创建多个工作表(Sheet)。 with pd.ExcelWriter("模型指标和损失值.xlsx")…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
