【Linux】进程间的通信----管道

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶🔹C++🔹Liunx
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

  • 一、什么是管道?
  • 二、管道的分类
    • 1. 匿名管道
    • 2. 命名管道
  • 三、匿名管道
    • 1、什么是匿名管道
    • 2、匿名管道的原理
    • 3、总体原理图
    • 4.pipe()指令详解
    • 5.匿名管道的使用
    • 6.匿名管道的特点
    • 7.管道运行的几种情况
  • 四、命名管道
    • 1、什么是命名管道
    • 2、命名管道原理
    • 命名管道的使用过程
    • mkfifo()详解

一、什么是管道?

管道(Pipe)是一种进程间通信机制,用于在相关进程之间传输数据。它是一种特殊的文件描述符,它可以连接一个进程的输出(写入端)到另一个进程的输入(读取端),从而使得这两个进程可以通过管道进行数据传输。

也就是说管道是单向传输的!现实生活中,我们所看听到的天然气管道、石油管道基本上都是单向传输的.
在这里插入图片描述

————————————————

历史上出现了许多通信机制,但是目前主流的进程通信只剩下了一小部分,管道之所以保留至今,是应为它没有多余的代码,而是巧妙的利用父子进程之间的特性,共用同一个文件进行信息的传输。

二、管道的分类

1. 匿名管道

匿名管道(Anonymous Pipe)是一种基于内存的管道,没有与文件系统中的任何文件相关联。它是通过pipe()系统调用创建的,通常只能用于在具有亲缘关系的进程之间传递数据。匿名管道只能在创建它的进程及其子进程之间使用,无法在其他进程之间共享。

2. 命名管道

命名管道(Named Pipe,也称FIFO)是一种基于文件系统的管道,它是通过文件系统中的特殊文件来实现的。命名管道有一个文件名和文件系统中的其他文件一样,可以被多个进程打开和使用,用于在不同的进程之间传递数据。使用命名管道需要调用mkfifo()函数来创建一个特殊的文件,然后打开这个文件并通过读写文件来传递数据。
命名管道通常用于需要在不同进程之间传递数据的场景,例如多进程并发编程、客户端-服务器架构、管道通信等。

三、匿名管道

1、什么是匿名管道

匿名管道(Anonymous Pipe)是进程间通信的一种机制,用于在具有亲缘关系(例如父子进程)或共享同一终端的兄弟进程之间传输数据。

  • 匿名管道是一种单向的数据流通道,它可以用于在进程之间传递数据。通常,一个进程作为管道的写入端(称为管道写入端),将数据写入管道;另一个进程作为管道的读取端(称为管道读取端),从管道中读取数据。

    • 匿名管道的创建是通过系统调用 pipe() 来完成的。

2、匿名管道的原理

管道通信的背后是进程之间通过管道进行通信。

我们知道一个进程要运行,首先要加载到内存,然后创建一个task_struct结构体,里面会有一个files_struct结构体,然后这个结构体里又有一个fd_array[]数组,每个元素指向对应的文件struct_file,里面包含了文件内容等。如下图: 👇在这里插入图片描述

此时我们fork之后的子进程会重新创建一份task_struct,内容继承父进程的,此时fd_array[]里的内容也被子进程继承,即父进程打开的文件 子进程也继承了下来。它们指向的文件是 相同的.

假设父进程3号文件描述符是读取文件的,4号文件描述符也用来写入文件的,子进程继承以后,fd=3也是用来读取文件的,fd=4也是用来写入文件的
在这里插入图片描述

此时我们想让父进程进行写入fd=4,子进程进行读取fd=3,所以父进程就要关闭读端fd=3,子进程关闭写端fd=4。
在这里插入图片描述

这样我们就做到了让不同的进程看到了同一份资源(通过fork子进程),而且通过文件描述符的方式完成了进程间的单向通信。

综上,管道内部本质大体是如下流程:
1️⃣ 父进程分别以读写方式打开一个文件
2️⃣ fork()创建子进程
3️⃣双方各自关闭不需要的文件描述符

3、总体原理图

在这里插入图片描述

4.pipe()指令详解

头文件:<unistd.h>
格式:int pipe(int pipefd[2])

  • pipefd[2]是一个输出型参数。 读写文件描述符,0:代表读, 1:代表写
  • 返回值:成功返回0,出错返回-1
  • pipe会创建一个内存级别的文件,它没有文件名,只能通过文件描述符来找,所以又称为“匿名文件(管道)

5.匿名管道的使用

#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
 
int main()
{
    // 1.创建管道
    int pipefd[2] = {0}; // pipefd[0] :读端, pipefd[1] :写端
    int n = pipe(pipefd);
    assert(n != -1);
    #ifdef DEBUG
    #endif
    // cout << pipefd[0] << "  " << pipefd[1] << endl;
    // 2.创建子进程
    pid_t id = fork();
    assert(id != -1);
 
    if (id == 0)
    {
        // 子进程
        // 3.构建单向通信的信道,父进程写入,子进程读取
        // 3.1关闭子进程不需要的fd
        close(pipefd[1]);
        char buffer[1024];
        while (true)
        {
            ssize_t s = read(pipefd[0], buffer, sizeof(buffer) - 1);
            if (s > 0)
            {
                buffer[s] = 0;
                cout << "child get a message [" << getpid() << "] Father# " << buffer << endl;
            }
        }
        exit(0);
    }
 
    // 父进程
    // 构建单向通信的信道
    // 3.1 关闭父进程不需要的fd
    close(pipefd[0]);
    string message = "我是父进程,我正在给你发消息";
    int count = 0;
    char send_buffer[1024];
    while (true)
    {
        // 3.2 构建一个变化的字符串
        snprintf(send_buffer, sizeof(send_buffer), "%s[%d] : %d", message.c_str(), getpid(), count++);
        // 3.3 写入
        write(pipefd[1], send_buffer, strlen(send_buffer));
        // 3.4 sleep
        sleep(1);
    }
 
    pid_t ret = waitpid(id, nullptr, 0);
    assert(ret > 0);
    close(pipefd[1]);
    return 0;
}

在这里插入图片描述

6.匿名管道的特点

1️⃣ 管道是用来进行具有血缘关系的进程进行进程间通信 — 常用于父子间通信
2️⃣ 管道具有通过让进程间协同,提供了访问控制
3️⃣ 管道提供的是面向字节流式的通信服务 — 面向字节流 — 通过定制协议实现
4️⃣ 管道是基于文件的,文件的生命周期是随进程的,即管道的生命周期也随进程的!
5️⃣ 管道是单向通信的,就是半双工通信的一种特殊方式.

7.管道运行的几种情况

写快,读慢写满就不能再写了
写慢,读快管道没有数据时,读必须等待

上面两种这是由访问控制提供的.

写关,读继续读会标识读到了文件结尾
写继续写,读关OS会终止写进程

四、命名管道

与匿名管道不同,命名管道不需要亲缘关系的进程之间,也不需要共享同一终端。任意进程可以通过打开命名管道的读取端和写入端来与其进行通信。

1、什么是命名管道

命名管道通过在文件系统中创建一个特殊的文件来实现通信。这个特殊的文件被称为FIFO(First-in, First-out)或命名管道。用于在无关的进程之间进行数据传输。

2、命名管道原理

和匿名管道一样,想让双方通信,必须先让双方看到同一份资源!它和匿名管道本质是一样的,只是看到资源的方式不同。

匿名管道是通过父子进程继承来看到同一份资源的,也叫做管道文件,这个文件是纯内存级的,所以没有名字,叫做匿名管道。
命名管道是在磁盘上有一个特殊的文件,这个文件可以被打开,但是打开后不会将内存中的数据刷新到磁盘。在磁盘上就有了路径,而路径是唯一的,所以双方就可以通过文件的路径 来看到同一份资源,即管道文件。

命名管道的使用过程

1️⃣ 创建命名管道:通过调用系统调用 mkfifo() 在文件系统中创建一个特殊的文件,这个文件就是命名管道。创建命名管道时,需要指定管道的名称和所需的权限。

2️⃣ 打开命名管道:进程通过调用系统调用 open() 来打开命名管道,得到一个文件描述符。进程可以通过打开具有相同名称的文件来打开命名管道的读取端和写入端。

3️⃣ 进程通信:一旦命名管道被打开,进程就可以使用文件描述符进行通信。每个进程可以选择读取端或写入端与命名管道进行交互。

4️⃣ 数据传输:进程在读取端通过调用 read() 系统调用从命名管道中读取数据,而在写入端通过调用 write() 系统调用将数据写入命名管道中。读取端和写入端可以通过文件描述符进行数据的发送和接收。

5️⃣ 关闭命名管道:进程完成通信后,可以通过调用 close() 关闭命名管道的文件描述符来释放资源。当所有对命名管道的引用都被关闭时,管道的文件系统条目将被删除。

mkfifo()详解

mkfifo [选项] 文件名
在程序中执行时创建int mkfifo(const char *filename,mode_t mode);

作用:创建上面提到的特殊文件----命名管道

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/782173.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

妈妈带女儿美在心里

在这个充满温情与惊喜的午后&#xff0c;阳光温柔地洒落在每一个角落&#xff0c;仿佛连空气弥漫着幸福的味道。就在这样一个平凡的时刻&#xff0c;一段关于爱与成长的温馨画面&#xff0c;悄然在网络上绽放&#xff0c;引爆了无数人的心弦——#奚梦瑶2岁女儿身高#&#xff0c…

在 VS Code 中自动化 Xcode 项目编译和调试

在 VS Code 中自动化 Xcode 项目编译和调试 在日常的开发工作中&#xff0c;Xcode 是 macOS、iOS、watchOS 和 tvOS 应用程序开发的主要工具。为了提高工作效率&#xff0c;许多开发者选择在 Visual Studio Code (VS Code) 中编辑代码&#xff0c;并希望能够直接从 VS Code 启…

【vue组件库搭建06】组件库构建及npm发包

一、格式化目录结构 根据以下图片搭建组件库目录 index.js作为入口文件&#xff0c;将所有组件引入&#xff0c;并注册组件名称 import { EButton } from "./Button"; export * from "./Button"; import { ECard } from "./Card"; export * fr…

网络通信总体框架

目录 网络通信 一、网络通信的定义与基本原理 二、网络通信的组成要素 三、网络通信的应用与发展 网络体系结构 一、网络体系结构的定义与功能 二、OSI七层参考模型 三、网络体系结构的重要性 网络核心与边缘 一、网络核心 1. 定义与功能 2. 组成部分 3. 技术特点 …

昇思25天学习打卡营第19天|LSTM+CRF序列标注

概述 序列标注指给定输入序列&#xff0c;给序列中每个Token进行标注标签的过程。序列标注问题通常用于从文本中进行信息抽取&#xff0c;包括分词(Word Segmentation)、词性标注(Position Tagging)、命名实体识别(Named Entity Recognition, NER)等。 条件随机场&#xff08…

01:spring

文章目录 一&#xff1a;常见面试题1&#xff1a;什么是Spring框架&#xff1f;1.1&#xff1a;spring官网中文1.2&#xff1a;spring官网英文 2&#xff1a;谈谈自己对于Spring IOC和AOP的理解2.1&#xff1a;IOCSpring Bean 的生命周期主要包括以下步骤&#xff1a; 2.2&…

国产化新标杆:TiDB 助力广发银行新一代总账系统投产上线

随着全球金融市场的快速发展和数字化转型的深入推进&#xff0c;金融科技已成为推动银行业创新的核心力量。特别是在当前复杂多变的经济环境下&#xff0c;银行业务的高效运作和风险管理能力显得尤为重要。总账系统作为银行会计信息系统的核心&#xff0c;承载着记录、处理和汇…

MySQL-行级锁(行锁、间隙锁、临键锁)

文章目录 1、介绍2、查看意向锁及行锁的加锁情况3、行锁的演示3.1、普通的select语句&#xff0c;执行时&#xff0c;不会加锁3.2、select * from stu where id 1 lock in share mode;3.3、共享锁与共享锁之间兼容。3.4、共享锁与排他锁之间互斥。3.5、排它锁与排他锁之间互斥3…

离线开发(VSCode、Chrome、Element)

一、VSCode 扩展 使用能联网的电脑 A&#xff0c;在VSCode官网下载安装包 使用能联网的电脑 A&#xff0c;从扩展下载vsix扩展文件 将VSCode安装包和vsix扩展文件通过手段&#xff08;u盘&#xff0c;刻盘 等&#xff09;导入到不能联网的离线电脑 B 中 在离线电脑 B 中安装…

计算机网络之无线局域网

1.无线局域网工作方式 工作方式&#xff1a;每台PC机上有一个无线收发机&#xff08;无线网卡&#xff09;&#xff0c; 它能够向网络上的其他PC机发送和接受无线电信号。 与有线以太网相似&#xff0c;无线局域网也是打包方式发送数据的。每块网卡都有一个永久的、唯一的ID号…

springboot配置扫描生效顺序

文章目录 举例分析项目结构如下noddles-user-backend 两个配置文件noddles-user-job 配置文件noddles-user-server 配置文件问题:server和Job启动时对应加载的数据库配置为哪一个&#xff1f; 总结 在微服务架构中&#xff0c;backend模块会定义一个基础的配置文件&#xff0c;…

java集合(2)

目录 一. Map接口下的实现类 1. HashMap 1.1 HashMap常用方法 2. TreeMap 2.1 TreeMap常用方法 3. Hashtable 3.1 Hashtable常用方法 4.Map集合的遍历 4.1 根据键找值 4.2 利用map中的entrySet()方法 二.Collections类 1.Collections类中的常用方法 三. 泛型 1. 为什…

运维锅总详解系统启动流程

本文详细介绍Linux及Windows系统启动流程&#xff0c;并分析了它们启动流程的异同以及造成这种异同的原因。希望本文对您理解系统的基本启动流程有所帮助&#xff01; 一、Linux系统启动流程 Linux 系统的启动流程可以分为几个主要阶段&#xff0c;从电源开启到用户登录。每个…

揭秘IP:从虚拟地址到现实世界的精准定位

1.IP地址介绍 1.内网 IP 地址&#xff08;私有 IP 地址&#xff09; 内网 IP 地址&#xff0c;即私有 IP 地址&#xff0c;是在局域网&#xff08;LAN&#xff09;内部使用的 IP 地址。这些地址不会在公共互联网中路由&#xff0c;因此可以在多个局域网中重复使用。私有 IP 地…

设计模式探索:责任链模式

1. 什么是责任链模式 责任链模式 (Chain of Responsibility Pattern) 是一种行为型设计模式。定义如下&#xff1a; 避免将一个请求的发送者与接收者耦合在一起&#xff0c;让多个对象都有机会处理请求。将接收请求的对象连接成一条链&#xff0c;并且沿着这条链传递请求&…

14-43 剑和诗人17 - ActiveRAG之主动学习

​​​​​ 大型语言模型 (LLM) 的出现开启了对话式 AI 的新时代。这些模型可以生成非常像人类的文本&#xff0c;并且比以往更好地进行对话。然而&#xff0c;它们在仅依赖预训练知识方面仍然面临限制。为了提高推理能力和准确性&#xff0c;LLM 需要能够整合外部知识。 检索…

文件存储的方法一

文章目录 概念介绍实现方法示例代码 我们在上一章回中介绍了"如何实现本地存储"相关的内容&#xff0c;本章回中将介绍如何实现文件存储.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在上一章回中介绍的本地存储只能存储dart语言中基本类型的数值…

ffmpeg图片视频编辑器工具的安装与使用

title: ffmpeg图片视频编辑器工具的安装与使用 tags: [ffmpeg, 图片, 音频, 视频, 工具, 流媒体] categories: [工具, ffmpeg] FFmpeg是一个开源的命令行工具&#xff0c;广泛用于处理视频和音频文件&#xff0c;包括转换格式、剪辑、混流、解码、编码等。以下是一些基本的FFmp…

Zabbix 的部署和自定义监控内容

前言 一个完整的项目的业务架构包括 客户端 -> 防火墙 -> 负载均衡层&#xff08;四层、七层 LVS/HAProxy/nginx&#xff09; -> Web缓存/应用层&#xff08;nginx、tomcat&#xff09; -> 业务逻辑层(php/java动态应用服务) -> 数据缓存/持久层&#xff08;r…

智慧水利的变革之路:如何通过大数据、物联网和人工智能构建高效、智能、可持续的水利管理新模式

目录 一、引言&#xff1a;智慧水利的时代背景与意义 二、大数据&#xff1a;水利管理的数据基石 &#xff08;一&#xff09;数据收集与整合 &#xff08;二&#xff09;数据分析与挖掘 三、物联网&#xff1a;水利管理的感知神经 &#xff08;一&#xff09;智能感知与监…