【Linux进程间通信】Linux匿名管道详解:构建进程间通信的隐形桥梁
📝个人主页🌹:Eternity._
⏩收录专栏⏪:Linux “ 登神长阶 ”
🌹🌹期待您的关注 🌹🌹
❀Linux进程间通信
- 📒1. 进程间通信介绍
- 📚2. 什么是管道
- 📜3. 匿名管道
- 🌞fork共享管道原理
- 🌙结合文件描述符
- ⭐站在内核角度
- 📝4. 管道的读写情况与特点
- 🎈管道的读写情况
- 🎩管道的特性
- 📖5. 总结
前言:当提及Linux系统中的进程间通信(IPC),管道(Pipes)无疑是最基础且广泛使用的一种机制。作为匿名通信的典范,管道为进程间数据交换提供了一个简单而有效的途径。在这个信息飞速传递的时代,掌握Linux管道的使用不仅是理解操作系统底层通信原理的关键一步,也是提升软件开发效率、构建复杂应用系统的必备技能
本篇文章将带您深入探索Linux进程间匿名通信的管道机制。我们将从管道的基本概念出发,逐步揭开其背后的工作原理,并通过实例演示如何在实际编程中创建、使用和维护管道。无论您是初学者,希望建立对Linux IPC的初步认识;还是经验丰富的开发者,渴望在现有基础上进一步精进;亦或是对系统编程充满好奇的学习者,渴望深入了解操作系统内部的奥秘,本文都将为您提供丰富的知识和实用的指导
我们将详细介绍管道的创建过程、数据读写操作、管道的生命周期管理以及常见的使用场景。 同时,我们还会探讨管道在并发编程中的表现,分析其在多进程环境下的行为特性,并提供相应的优化策略。通过理论与实践相结合的方式,相信您能够全面掌握Linux进程间匿名通信的管道技术,为您的软件开发之路增添一份坚实的力量
让我们一同踏上这段探索之旅,揭开Linux管道的神秘面纱,领略其在进程间通信中的独特魅力!
📒1. 进程间通信介绍
进程间通信(Interprocess communication,IPC)是指在不同的进程之间传播或交换信息。由于进程的用户空间是互相独立的,一般而言不能互相访问,但存在一些双方都可以访问的介质或系统空间来实现通信
-
原理: 进程间通信主要依赖于双方都可以访问的介质或系统空间。这些介质包括共享内存区、系统空间以及双方都可以访问的外设(如磁盘上的文件、数据库中的表项等)。然而,广义上的通过这些方式进行的通信一般不算作“进程间通信”。进程间通信更常见的是通过一组编程接口来实现,这些接口允许程序员协调不同的进程,使它们能在一个操作系统里同时运行,并相互传递、交换信息
-
必要性: 即使只有一个用户发出要求,也可能导致一个操作系统中多个进程的运行。这些进程之间必须互相通信,以协调它们的行为和共享资源。进程间通信使得一个程序能够在同一时间里处理许多用户的要求
📚2. 什么是管道
- 管道是Unix中最古老的进程间通信的形式
- 我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”
管道分为:匿名管道和命名管道
,本篇我们主要来了解一下匿名管道
📜3. 匿名管道
匿名管道是Linux中一种非常基础的进程间通信(IPC)方式,其本质上是一种内存级的文件,专门用于父子进程间或具有亲缘关系的进程间的通信
创建匿名管道
#include <unistd.h>//功能:创建一无名管道
//原型
int pipe(int fd[2]);//参数
//fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
//返回值:成功返回0,失败返回错误代码
实例代码:
#include <iostream>
#include <cassert>
#include <cstring>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>#define MAX 1024using namespace std;int main()
{// 1. 建立管道int pipefd[2] = {0};int n = pipe(pipefd);assert(n == 0);// 定义 n(void)n;// 查看文件描述符cout << "pipefd[0]: " << pipefd[0] << ", pipefd[1]: " << pipefd[1] << endl;// 2. 创建子进程pid_t id = fork();if(id < 0){perror("fork");return 1;}// 子写,父读,// 3. 关闭父子不需要的fd,形成单向通信的管道if(id == 0){// 子进程close(pipefd[0]);// 写入int cnt = 10;while(cnt){char message[MAX];snprintf(message, sizeof(message), "hello father, I am child, pid: %d, cnt: %d", getpid(), cnt);cnt--;write(pipefd[1], message, strlen(message));cout << "writing cnt: " << cnt << endl;}exit(0);}// 父进程close(pipefd[1]);// 读取char buffer[MAX];while(true){ssize_t n = read(pipefd[0], buffer, sizeof(buffer)-1);if(n == 0){cout << "child qiut, read tail" << endl;break;}else if(n > 0){buffer[n] = 0; // '\0', 当作字符串cout << getpid() << ": " << "child say: " << buffer << " to me!" << endl;}}pid_t rid = waitpid(id, nullptr, 0);if(rid == id){cout << "wait seccess" << endl;}return 0;
}
🌞fork共享管道原理
🌙结合文件描述符
⭐站在内核角度
📝4. 管道的读写情况与特点
🎈管道的读写情况
- 正常情况,如果管道没有数据了,读端必须等待,直到有数据为止(写端写入数据)
- 正常情况,如果管道被写满了,写端必须等待,直到有空间为止(读端读走数据)
我们让读端一直读,而写端在写入部分文件后让它sleep一段时间,我们这是来观察一下读端的情况
代码示例:(C++):
if(id == 0)
{// 子进程close(pipefd[0]);// 写入int cnt = 10000;while(cnt){char message[MAX];snprintf(message, sizeof(message), "hello father, I am child, pid: %d, cnt: %d", getpid(), cnt);cnt--;write(pipefd[1], message, strlen(message));// 在正常写入一次后,sleep,父进程读取不做修改sleep(4); }exit(0);
}
当我们的管道被写满了的时候,写端就不能在进行写入了,我们必须等待读端将数据读取走才能继续往管道里面写入,我们让读端休眠上几面,让写端一直写
代码示例:(C++):
if(id == 0)
{// 子进程close(pipefd[0]);// 写入int cnt = 0;while(true){char message[MAX];snprintf(message, sizeof(message), "hello father, I am child, pid: %d, cnt: %d", getpid(), cnt);cnt++;write(pipefd[1], message, strlen(message));// 在正常写入一次后,sleep,父进程读取不做修改cout << "writing cnt: " << cnt << endl; }exit(0);
}
- 写端关闭,读端一直读取,读端会读到read返回值为0,表示读到文件结尾
- 读端关闭,写端一直写入,0S会直接杀掉写端进程,通过想目标进程发送SIGPIPE(13)信号,终止目标进程
写端关闭代码示例:(C++):
if(id == 0)
{// 子进程close(pipefd[0]);// 写入int cnt = 0;while(true){char message[MAX];snprintf(message, sizeof(message), "hello father, I am child, pid: %d, cnt: %d", getpid(), cnt);cnt++;write(pipefd[1], message, strlen(message));//sleep(2);cout << "writing cnt: " << cnt << endl;// 在写入两次时,我们将子进程的写入关闭if(cnt == 2){close(pipefd[1]);break;}}exit(0);
}// 父进程
close(pipefd[1]);// 读取
char buffer[MAX];
while(true)
{sleep(4);ssize_t n = read(pipefd[0], buffer, sizeof(buffer)-1);// 当 n == 0 时,代表read已经读到文件结尾了if(n == 0){cout << "child qiut, read tail" << endl;break;}else if(n > 0){buffer[n] = 0; // '\0', 当作字符串cout << getpid() << ": " << "child say: " << buffer << " to me!" << endl;}
}
我们这样设计代码,先让子进程写入之后,关闭掉pipefd[1],然后观察父进程是否会打印,我们需要的代码
读端关闭代码示例:(C++):
// 父进程
close(pipefd[1]);// 读取
char buffer[MAX];
while(true)
{//sleep(4);ssize_t n = read(pipefd[0], buffer, sizeof(buffer)-1);if(n == 0){cout << "child qiut, read tail" << endl;break;}else if(n > 0){buffer[n] = 0; // '\0', 当作字符串cout << getpid() << ": " << "child say: " << buffer << " to me!" << endl;}cout << "father return val(n)" << n << endl;sleep(1);// 打印一次后,我们退出循环 break;
}// 关闭 pipefd[0],停止读取
cout << "close point read" << endl;
close(pipefd[0]);sleep(3);int status = 0;
pid_t rid = waitpid(id, &status, 0);
if(rid == id)
{cout << "wait seccess, exit sig: " << (status&0x7f) << endl;
}
注意:
当前状态码 & 0x7f
可以查看到最后的退出码
🎩管道的特性
管道的5种特性
- 匿名管道,可以允许具有血缘关系的进程之间进行进程间通信,常用与父子,仅限于此
- 匿名管道,默认给读写端要提供同步机制
- 面向字节流的入
- 管道的生命周期是随进程的
- 管道是单向通信的,半双工通信的一种特殊情况
在了解完管道的这些情况和特征后,我们可以利用管道来写一个简单的线程池
线程池代码链接
📖5. 总结
在探索Linux进程间匿名通信的管道机制这一旅程的尾声,我们不禁对Linux操作系统的精妙设计和强大功能有了更深一层的理解。管道,作为进程间通信的基础而又高效的工具,不仅简化了数据在不同进程间的流动过程,还极大地促进了多任务并发执行的灵活性
通过本文的学习,我们见证了管道从创建到使用的全过程,理解了其背后的工作原理,并掌握了如何在实际编程中利用管道来实现进程间的数据交换。从
pipe()
函数的调用,到文件描述符的分配,再到数据的读写操作,每一个步骤都蕴含着Linux系统设计的智慧与匠心
但Linux提供的进程间通信机制远不止于此。命名管道、消息队列、共享内存、信号量以及套接字等多种IPC方式,各自拥有独特的优势和适用场景。在未来的学习与实践中,我们可以继续深入探索这些机制,以更加灵活多样的方式实现进程间的协同工作
让我们以更加饱满的热情和坚定的信心,继续前行在Linux系统编程的学习之路上!
希望本文能够为你提供有益的参考和启示,让我们一起在编程的道路上不断前行!
谢谢大家支持本篇到这里就结束了,祝大家天天开心!
相关文章:
【Linux进程间通信】Linux匿名管道详解:构建进程间通信的隐形桥梁
📝个人主页🌹:Eternity._ ⏩收录专栏⏪:Linux “ 登神长阶 ” 🌹🌹期待您的关注 🌹🌹 ❀Linux进程间通信 📒1. 进程间通信介绍📚2. 什么是管道📜3…...
【力扣 | SQL题 | 每日三题】力扣1148, 1327, 1211, 1174
1. 力扣1148:文章浏览1 1.1 题目: Views 表: ------------------------ | Column Name | Type | ------------------------ | article_id | int | | author_id | int | | viewer_id | int | | view_date …...
【鸿蒙开发】详解GridRowSizeOption的尺寸属性
文章目录 1. 尺寸属性的含义2. 为什么要有这几个属性3. 具体作用4. 如何使用总结 在鸿蒙(HarmonyOS)开发中,布局的灵活性和适应性对于构建高质量的应用至关重要。 GridRowSizeOption是鸿蒙开发框架提供的一个布局属性,用于定义网…...
Sping源码:三级缓存
目录 一、概念1、三级缓存的作用2、循环依赖的含义 二、代码1、代码下载2、文件功能介绍3、源码分析3.1、找到获取A对象的位置,打断点进行debug操作3.2、一步步找到在A对象中注入B对象的位置3.3、一步步找到B对象注入A对象的位置3.4、往下找到通过三级缓存解决循环依…...
latex有哪些颜色中文叫什么,Python绘制出来
latex有哪些颜色中文叫什么,Python绘制出来 为了展示xcolor包预定义的颜色及其对应的中文名称,并使用Python打印出来,我们可以先列出常见的预定义颜色名称,然后将它们翻译成中文,并最后用Python打印出来。 步骤 列出…...
C语言进程
什么是进程 什么是程序 一组可以被计算机直接识别的 有序 指令 的集合。 通俗讲:C语言编译后生成的可执行文件就是一个程序。 那么程序是静态还是动态的? 程序是可以被存储在磁盘上的,所以程序是静态的。 那什么是进程 进程是程序的执行过…...
C#基础(4)封装——成员方法
前言 我们在上一节学习了关于类的成员变量的使用,甚至也看到了相应的成员方法,我们可以将二者理解为类里面的变量和函数。 如果我这样说你肯定就能很快理解成员方法是什么作用了。 C#中设计成员方法的目的是为了将相关的功能代码组织在一起࿰…...
springbot,JWT令牌的使用。实现http请求拦截校验。
JWT 由三部分组成,用点(.)分隔 Header(头部) Payload(负载)Signature(签名) 一、原理 Jwt原理其实很简单,在后端首先要有个拦截器,他会拦截所有http请求&…...
【SQL】DDL语句
文章目录 1.SQL通用语法2.SQL的分类3.DDL3.1数据库操作3.2 表操作3.2.1 表操作--数据类型3.2.2 表操作--修改3.2.3 表操作--删除 SQL 全称 Structured Query Language,结构化查询语言。操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准 。…...
【分页】Spring Boot 列表分页 + javaScript前台展示
后端: 准备好查询实体与分页实体 1、分页工具实体 package com.ruoyi.dms.config;import com.alibaba.nacos.api.model.v2.Result; import lombok.Data;import java.io.Serializable; import java.util.List;/*** author 宁兴星* description: 列表返回结果集*/ …...
「安装」 Windows下安装CUDA和Pytorch
「安装」 Windows下安装CUDA和Pytorch 文章目录 「安装」 Windows下安装CUDA和PytorchMac、Linux、云端Windows安装CUDA安装miniconda安装PyTorch测试总结 其他 Mac、Linux、云端 Mac、Linux、云端安装Miniconda和Pytorch的方法参考其他资料。 Windows 下面进行Windows下安装…...
c语言基础作业
选择题 1.1、以下选项中,不能作为合法常量的是 __________ A)1.234e04 B)1.234e0.4C)1.234e4 D)1.234e0 1.2、以下定义变量并初始化错误的是_____________。 A) char c1 ‘H’ ; B) char c1 9…...
uniapp view增加删除线
推荐学习文档 golang应用级os框架,欢迎stargolang应用级os框架使用案例,欢迎star案例:基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识,这里有免费的golang学习笔…...
[Day 83] 區塊鏈與人工智能的聯動應用:理論、技術與實踐
區塊鏈在物聯網中的應用 區塊鏈技術與物聯網(IoT)結合,為許多領域提供了強大的解決方案。傳統的IoT架構常面臨數據隱私和安全問題,而區塊鏈的去中心化和加密技術則能有效增強IoT系統的安全性、透明性和效率。本文將探討區塊鏈如何…...
Java ReentrantLock
目录 1 互斥性 2 公平性 3 可重入性 4 获取和释放锁 5 尝试获取锁 6 可中断的锁定 7 条件变量 8 性能 9 使用场景 ReentrantLock 是 Java 提供的一种可重入的互斥锁,位于 java.util.concurrent.locks 包中,它实现了 Lock 接口。这个锁提供了与内…...
【Linux系统编程】第二十六弹---彻底掌握文件I/O:C/C++文件接口与Linux系统调用实践
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、回顾C语言文件接口 1.1、以写的方式打开文件 1.2、以追加的方式打开文件 2、初步理解文件 2.1、C文件接口 3、进一步理…...
数据分析-29-基于pandas的窗口操作和对JSON格式数据的处理
文章目录 1 窗口操作1.1 滑动窗口思想1.2 函数df.rolling2 JSON格式数据2.1 处理简单JSON对象和JSON列表2.1.1 处理简单的JSON结构2.1.2 处理空字段2.1.3 获取部分字段2.2 处理多级json2.2.1 展开所有级别(默认)2.2.2 自定义展开层级2.3 处理嵌套列表JSON3 参考附录1 窗口操作 …...
Ubuntu-WSL2一键设置代理操作
现状: Window11中拥有自己的代理软件 ,可以科学上网已在WSL2中安装Ubuntu22.04 需求: Ubuntu-WSL2实现科学上网 实现: 参考:为 WSL2 一键设置代理 Linux 子系统中的网关指向的是 Windows,DNS 服务器指…...
ubuntu命令行连接wifi
在Ubuntu上,你可以通过命令行连接到Wi-Fi网络。以下是详细步骤,主要使用 nmcli 和 nmtui 命令。 方法 1:使用 nmcli nmcli 是 NetworkManager 的命令行界面,用于管理网络连接。以下是使用 nmcli 连接到 Wi-Fi 网络的步骤&#x…...
日常工作第10天:
vim 批量编辑的命令是 移动光标到列首。按键 CtrlV 进入 Visual block 模式,标记你想要进行编辑的列(HJKL可以向左下上右移动光标)。按键 ShiftI 进入 Insert 模式,在列首输入文本;或者 Shift A,追加文本…...
CNN+Transformer解说
CNN(卷积神经网络)和Transformer是两种在深度学习领域广泛使用的模型架构,它们在处理不同类型的数据和任务时各有优势。 CNN擅长捕捉局部特征和空间层次结构,而Transformer擅长处理序列数据和长距离依赖关系。 将CNN与Transform…...
jmeter中token测试
案例: 网站:http://shop.duoceshi.com 讲解:用三个接口来讲解 第一个接口code:GET http://manage.duoceshi.com/auth/code 第二个登录接口:http://manage.duoceshi.com/auth/login 第三个接口:http://…...
基于解压缩模块的JPEG同步重压缩检测论文学习
一、论文基本信息: 论文题目:基于解压缩模块的JPEG同步重压缩检测 作者:王金伟1 ,胡冰涛1 ,张家伟1 ,马 宾2 ,罗向阳3 (1.南京信息工程大学计算机学院、网络空间安全学院…...
音视频入门基础:FLV专题(7)——Tag header简介
一、引言 从《音视频入门基础:FLV专题(3)——FLV header简介》中可以知道, 在FLV header之后,FLV文件剩下的部分应由PreviousTagSize和Tag组成。FLV文件 FLV header PreviousTagSize0 Tag1 PreviousTagSize1 Ta…...
【Linux 报错】“make: ‘xxxx‘ is up to date.” 解决办法
一、报错原因 我们使用 make 命令,想要将 text.c 文件编译形成 可执行文件 text 时,报错如下 make: test is up to date. 中文含义:test 文件已经达到最新状态 意思是: test.c 文件里面的 所有源代码都没有修改过,你…...
【FPGA开发】Xilinx FPGA差分输入时钟的使用方法
正文 以前在使用ZYNQ的领航者ZYNQ7020进行FPGA学习时,它们使用的单端50M的输入时钟,在verlog代码编写上比较简单,而现在使用Alinx的AXU3EG开发板时,发现它使用的是200M的差分输入时钟,哪这个时候,输入时钟要…...
面试扩展知识点
1.C语言中分为下面几个存储区 栈(stack): 由编译器自动分配释放堆(heap): 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收全局区(静态区): 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域&#…...
【经验分享】MyCAT 中间件
学习了一下数据量过大的解决方案,使用 MyCAT 中间件。 MyCAT 可以解决分布式事务、读写分离、主从、分片等一系列MySQL集群和分布式问题。 整体过程可以概括为拦截 - 分发 - 响应 例如设置 MyCAT 分片规则为每500万条数据就换一个数据库存储。 分库分表的中心思想都是将数据…...
Kotlin:1.8.0 的新特性
一、概述 Kotlin 1.8.0版本英语官方文档 Kotlin 1.8.0 中文官方文档 The Kotlin 1.8.0 release is out and here are some of its biggest highlights: Kotlin 1.8.0发布了,下面是它的一些亮点: JVM 平台新增实验性函数:递归复制或删除目录内容改进了 …...
深度学习之开发环境(CUDA、Conda、Pytorch)准备(4)
目录 1.CUDA 介绍 1.1 CUDA 的基本概念 1.2 CUDA 的工作原理 1.3 CUDA 的应用领域 2. 安装CUDA 2.1 查看GPU版本 2.2 升级驱动(可选) 2.3 查看CUDA版本驱动对应的支持的CUDA ToolKit工具包 2.4 下载Toolkit 2.5 安装(省略࿰…...
做地方黄页网站/怎么进行网络营销
近日,阿里云一站式应用研发平台EMAS 2.0正式发布,本次将全新发布包括Serverless、低代码开发平台Mobi、AI工具箱、业务组件等产品服务,同时推出面向中小微企业和开发者的免费套餐扶持计划。开发者可在云时代以更低成本、更便捷地完成应用的开…...
濮阳河南网站建设/网络营销推广要求
Push-Pull推挽输出Open-Drain开漏输出原理输出的器件是指输出脚内部集成有一对互补的MOSFET,当Q1导通、Q2截止时输出高电平;而当Q1截止导通、Q2导通时输出低电平开漏电路就是指以MOSFET的漏极为输出的电路。指内部输出和地之间有个N沟道的MOSFET(Q1)&…...
如何把网站主关键词做到百度首页/网上做广告推广
MySQL 有一个和优秀的语法 create table ... like , 可以快速复制一张表,创建其副本。 PostgreSQL 也有类似的语法,而且更加灵活,不过要注意些细节。先来看看MySQL 语法: create table ... like原始表T1,结…...
国内it外包龙头企业/衡阳seo优化首选
2019独角兽企业重金招聘Python工程师标准>>> Sublime Text http://www.sublimetext.com 官网 http://www.sublimetext.com/2 官网 http://www.sublimetext.com/3 官网 1、插件安装 直接安装下载插件,解压至Packages文件夹中。在这里可以打开Packages文件…...
盐城有没有做网站吗/seo是免费的吗
作为程序员,相较于其它行业的人们面试的时候有个很痛苦的问题就是,很注重基础的考察,特别是数据结构基础的考察,不管你经验多么的丰富,特别是职业生涯中后期侧重于架构或者更上层的开发,你往往会忽略了基础…...
怎样自己开网站赚钱/公众号免费推广平台
// 02ProcessList.cpp文件 #include "stdafx.h" #include <windows.h> #include <tlhelp32.h> // 声明快照函数的头文件 int main(int argc, char* argv[]) { PROCESSENTRY32 pe32; // 在使用这个结构之前,先设置它的大小 pe32.dwSize …...