Linux——进程间通信:管道

我们在开发过程中,可能会碰到两个或多个进程需要协同进行,这两个进
程之间有着一定的关系,这个进程可能会需要另一个进程的某些消息来达
到自己的目的,或者是一个进程控制着另一个进程,又或者是需要某种资
源的共享。但是我们知道进程具有独立性,进程是不可能直接将自己的资
源交给其他进程的。所以就会有进程间通信,它是通过不同进程间能看到
同一份资源,通过这份资源来实现进程资源的传输等等进程间操作。所以
今天就由我来介绍进程间通信的其中一种方式:管道。

进程间通信是操作系统中让进程间具有:数据传输、资源共享、通知事件、进程控制的功能,那既然是功能,就会有很多种方式,下面的管道是其中一种方式。

a. 管道是什么?

我们在使用shell的时候,有时候会使用这样的命令:
在这里插入图片描述
而中间的符号就是管道的意思,我们知道ps是一个命令,那它就是一个进程,gre也是一个进程,首先ps axj命令把系统中运行的进程都要准备打印到屏幕上,但是显然它没有,而是把这份资源通过管道传输给grep这个进程,而grep进程接收到这份资源后,进行过滤出有关bash的进程再输出到屏幕上。
在这其中ps和grep是两个进程,但是ps把它产生的资源给了grep进程。而他们中间的传输数据用到的就是管道。
进程间通信的本质也是如此:通过让不同的进程能够看到同一份资源,而这份资源通常由操作系统提供。

b. 匿名管道

而管道又分为匿名管道和命名管道,上面的命令行中的管道我们可以看到它是没有名字的,它就是匿名管道,而这是命令行的匿名管道,我们代码中的匿名管道是什么呢?
在这里插入图片描述
这就收我们使用到的接口,他的大致意思是当我们使用这个接口的时候需要传入一个大小两个整形的数组为输出型参数,然后,这个数组中会存入两个被不同方式(读和写)打开的同一个管道文件fd。
那现在我们该如何实现不同进程间通信呢?
在这里插入图片描述
在这里插入图片描述
可以看到我们的打印是由父进程进行的,但是数据是由子进程提供的。这样就实现了进程间通信。

c. 匿名管道的原理

而上述进程间通信则是利用了操作系统创建子进程的特点,我们在创建子进程的同时,子进程会继承父进程的内核数据结构,进程pcb、文件描述符表等等都会被继承(拷贝)下来,所以子进程和父进程的进程描述符表中能看到同一个文件结构体指针,也就能看到同一份文件。
pipe这个接口就只是以读和写的方式打开了同一个文件,然后返回两个结构体的指针下标。
这个时候我们创建子进程,则这两个文件fd也会被子进程看到,假如我们要让子进程写(输出数据),父进程(读)接收数据,则需要子进程关闭文件的读端(关闭以写方式打开的文件fd),父进程关闭写端。形成信道。要让子进程接收数据,父进程输出数据的话反过来就可以。
需要注意的是,这个被打开的文件,就是管道文件,这个文件也是内存级文件,也就是使用pipe接口时,操作系统会在内存中创建一个内存级文件,供进程使用。
上面说了,使用pipe后会以不同方式打开同一个文件,而文件被打开主要部分有三个:文件结构体,文件页缓冲区,文件的读写方法集。在这里我们就要明确一点,当一个进程以不同方式(读和写)打开一个文件的时候,内存中只会有一个该文件的页缓冲区,读写方法集,但是会有两个文件结构体,因为在文件上读和写,它们的位置大概率会不同。所以是会有两个文件结构体:

在这里插入图片描述
有人会提出疑问,为什么要关闭父子进程的某个读写呢?不关闭不是双向通信了吗?
其实这是为了管道文件的实现的简便,如果支持双向通信的话,识别页缓冲区的数据就得需要分辨是哪个进程需要接收或者是哪个进程发出的,如果是多个消息挤在一起会很麻烦,所以管道通信是单向的。如果想要实现双向通信可以使用两个管道。
以上我们让父子两个进程看到了同一份资源(管道文件),从而能够使父子进程实现进程间通信。那既然父子间能够通过管道文件通信,那么两个子进程能不能实现通信呢?一个进程的父进程和它的子进程能不能实现通信呢?显然是可以的,都是利用了操作系统创建子进程的特点。但是如果是两个毫不相关的进程呢?通过这样的方式可以实现进程间通信吗?那就不行了。所以:匿名管道适用于拥有“血缘关系”的进程。

d. 匿名管道的特点

我们首先让写端一直写入数据但是不读:
在这里插入图片描述

在这里插入图片描述

可以看到,当我们只写不读时,当我们写到一定程度,就不会再写了,这其实是缓冲区已经满了。我们可以通过代码来查看它这个缓冲区有多大,具体方法是让它一次写入一字节:
在这里插入图片描述
而65535是63KB。那说明我这个Linux系统中的匿名管道文件的缓冲区大小是63KB。
如果是只写不读呢?
在这里插入图片描述
在这里插入图片描述
负责读的父进程则会一直阻塞在read函数
现在我们试着关闭写端:
在这里插入图片描述
读端会一直读到零。
如果关闭写端呢?
在这里插入图片描述
在这里插入图片描述

这里我们直接让父进程退出,但是子进程可没有退出。所以我们会得出,当读端关闭时,写端也会直接关闭。
而这里的写端进程关闭是被操作系统使用13号信号杀掉的,我们可以通过回收子进程得知:
在这里插入图片描述

在这里插入图片描述

所以我们会总结出匿名管道的四种情况:

如果管道中没有了数据,读端要一直等待。
如果管道写满了数据,则必须等读端读走数据,直到有空间写入。
写端关闭,读端的read函数会返回0。
读端关闭时,写端进程会关闭。

e. 命名管道

既然有匿名管道,那就有命名管道。
命名管道和匿名管道的原理基本一样,我们会先使用mkfifo命令创建一个管道文件:
在这里插入图片描述
现在我们使用一下这个文件:
当我们向这个文件写入时:
在这里插入图片描述
光标会直接卡住,需要我们在另一个渠道将文件中的内容读出来。
在这里插入图片描述
这也是命名管道在命令行中的使用方式
命名管道它本质上还是一个内存文件,它不会将数据存储到磁盘中。这里的文件名也只是作为内存文件的一种映射。这个文件的存在是为了实现进程间通信的。下面我们来看看代码的命名管道怎么使用:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
它的原理基本上与匿名管道一致。而命名管道就可以进行毫不相关的进程间的通信,只要两个进程中以一个读一个写的方式打开命名管道文件就可以实现进程间通信。因为路径是唯一的,我们可以使用路径+文件名的方式让不同进程看到同一份资源。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Blazor入门100天 : 自做一个支持长按事件的按钮组件

好长时间没继续写这个系列博客了, 不知道大家还记得我吗? 话不多说,直接开撸. 配套源码 demo https://blazor.app1.es/b19LongPressButton ####1. 新建 net8 blazor 工程 b19LongPressButton 至于用什么模式大家各取所需, 我创建的是ssr单工程, 如果大家不小心建立错了按页…

C#上位机与三菱PLC的通信03--MC协议之A-1E报文解析

1、MC协议帧 MC协议可以在串口通信,也可以在以太网通信,有A-1E和Qna-3E两种模式,这两种都是三菱PLC通信协议中比较常用的两种,一般我们使用比较多的是以太网通信,对于FX5U系列/Q系列/Qna系列/L系列的PLC,…

深度学习入门笔记(八)可以不断思考的模型:RNN与LSTM

8.1 循环神经网络RNN 之前学到的 CNN 和全连接,模型的输入数据之间是没有关联的,比如图像分类,每次输入的图片与图片之间就没有任何关系,上一张图片的内容不会影响到下一张图片的结果。但在自然语言处理领域,这就成了…

spring boot(2.4.x 开始)和spring cloud项目中配置文件application和bootstrap加载顺序

在前面的文章基础上 https://blog.csdn.net/zlpzlpzyd/article/details/136060312 spring boot 2.4.x 版本之前通过 ConfigFileApplicationListener 加载配置 https://github.com/spring-projects/spring-boot/blob/v2.3.12.RELEASE/spring-boot-project/spring-boot/src/mai…

Redis Centos7 安装到启动

文章目录 安装Redis启动redis查看redis状况连接redis服务端 安装Redis 1.下载scl源 yum install centos-release-scl-rh2.下载redis yum install rh-redis5-redis 3. 创建软连接 1.cd /usr/bin 2. In -s /opt/rh/rh-redis5/root/usr/bin/redis-server ./redis-server 3. …

【RT-DETR进阶实战】利用RT-DETR进行过线统计(可用于人 、车过线统计)

👑欢迎大家订阅本专栏,一起学习RT-DETR👑 一、本文介绍 Hello,各位读者,最近会给大家发一些进阶实战的讲解,如何利用RT-DETR现有的一些功能进行一些实战, 让我们不仅会改进RT-DETR,也能够利用RT-DETR去做一些简单的小工作,后面我也会将这些功能利用PyQt或者是p…

机器学习系列——(十九)层次聚类

引言 在机器学习和数据挖掘领域,聚类算法是一种重要的无监督学习方法,它试图将数据集中的样本分组,使得同一组内的样本相似度高,不同组间的样本相似度低。层次聚类(Hierarchical Clustering)是聚类算法中的…

幻兽帕鲁服务器创建私服教程(新版教程更简单)

幻兽帕鲁官方服务器不稳定?自己搭建幻兽帕鲁服务器,低延迟、稳定不卡,目前阿里云和腾讯云均推出幻兽帕鲁专用服务器,腾讯云直接提供幻兽帕鲁镜像系统,阿里云通过计算巢服务,均可以一键部署,鼠标…

项目02《游戏-07-开发》Unity3D

基于 项目02《游戏-06-开发》Unity3D , 接下来做UI框架的逻辑系统,管理器和UI背包, 首先闯将UI框架的两个重要脚本 BasePanel.cs 和 UIManager.cs , 双击BasePanel.cs脚本修改代码: using UnityEngine; pu…

【java苍穹外卖项目实战一】苍穹外卖项目介绍

文章目录 1、项目介绍1、项目概述2、 产品原型3、技术选型 1、项目介绍 在开发苍穹外卖这个项目之前,我们需要全方位的来介绍一下当前我们学习的这个项目。接下来,我们将从项目简介、产品原型、技术选型三个方面来介绍苍穹外卖这个项目。 1、项目概述 …

绝缘栅极晶体管IGBT

IGBT(绝缘栅极晶体管): 常用于百V百A级使用,外观上看相比于MOS最大的区别是比较大,mos主要用于中小功率器件中。 本质是一个电子开关,相比于MOS和三极管来说其最大的特点是耐压很高,可达6000V以上&#xf…

【LeetCode每日一题】525连续数组 303区域和检索(前缀和的基本概念和3个简单案例)

前缀和 // 构造prefix let prefix [0] arr.forEach(num > {prefix.push(prefix.at(-1) num); })如果想要计算某个区间 i 到 j 这个子数组的和时,可以根据 prefix[j1] - prefix[i] 获得。 例题1:303.区域和检索 - 数组不可变 给定一个整数数组 num…

【开源】SpringBoot框架开发考研专业课程管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 考研高校模块2.3 高校教师管理模块2.4 考研专业模块2.5 考研政策模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 考研高校表3.2.2 高校教师表3.2.3 考研专业表3.2.4 考研政策表 四、系统展示五、核…

npm---设置淘宝镜像时报“certificate has expired“的错误

今天使用vue create my-app 创建项目时,竟然报错: Error: Command failed: npm info vue-cli-version-marker --json --registryhttps://registry.npm.taobao.org npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request t…

c语言中的模拟多态性

在C语言中模拟多态性 多态性是面向对象编程中的一个核心概念,它允许我们通过一个共同的接口来操作不同的数据类型。虽然C语言是一种过程式语言,本身不直接支持面向对象的特性,如继承、封装和多态,但我们可以通过一些技巧来模拟这些…

算法之双指针系列1

目录 一:双指针的介绍 1:快慢指针 2:对撞指针 二:对撞指针例题讲述 一:双指针的介绍 在做题中常用两种指针,分别为对撞指针与快慢指针。 1:快慢指针 简称为龟兔赛跑算法,它的基…

机器学习11-前馈神经网络识别手写数字1.0

在这个示例中,使用的神经网络是一个简单的全连接前馈神经网络,也称为多层感知器(Multilayer Perceptron,MLP)。这个神经网络由几个关键组件构成: 1. 输入层 输入层接收输入数据,这里是一个 28x…

跳过mysql5.7密码并重置密码 shell脚本

脚本 目前只是验证了5.7 版本是可以的,8.多的还需要验证 以下是一个简单的Shell脚本,用于跳过MySQL密码设置并重置密码: #!/bin/bash yum install psmisc -y# 停止MySQL服务 sudo service mysqld stop# 跳过密码验证 sudo mysqld --skip-g…

【Linux】进程学习(二):进程状态

目录 1.进程状态1.1 阻塞1.2 挂起 2. 进程状态2.1 运行状态-R进一步理解运行状态 2.2 睡眠状态-S2.3 休眠状态-D2.4 暂停状态-T2.5 僵尸状态-Z僵尸进程的危害 2.6 死亡状态-X2.7 孤儿进程 1.进程状态 1.1 阻塞 阻塞:进程因为等待某种条件就绪,而导致的…

Elasticsearch: 非结构化的数据搜索

很多大数据组件在快速原型时期都是Java实现,后来因为GC不可控、内存或者向量化等等各种各样的问题换到了C,比如zookeeper->nuraft(https://www.yuque.com/treblez/qksu6c/hu1fuu71hgwanq8o?singleDoc# 《olap/clickhouse keeper 一致性协调服务》)&a…