linux进程间通信——进程间通信概念、最基本通信——管道文件

news2024/11/15 20:57:17

        前言: 本节内容将要讲解进程间通信。 之前我们说过进程之间是相互独立的, 但是,相互独立并不代表不能进行数据的输送。就好比我和你是相互独立的, 但是我们可以成为朋友, 可以互赠礼物。 而我们一般而言的, 两个或者多个进程之间实现数据层面的交互, 就叫做进程间的通信。现在, 开始我们的讲解吧。

        ps:本节内容涉及到进程,系统文件接口相关的知识, 建议友友们了解相关知识之后再学习本节内容! 

 

什么是进程间通信

         什么是进程间通信, 其实前言已经提到过, 这里简单的说一下就是:两个或者多个进程实现数据层面的交互,就叫做进程间通信。 ——需要注意的是, 因为进程独立性的存在, 导致进程通信的成本比较高。

为什么要有进程间通信 

        为什么要有进程间通信, 为什么一个进程要给另一个进程发送数据? ——发送基本指令、发送命令、某种协同、通知。——是为了让多个进程之间相互协同起来。这就有了基本的需求, 所以最终就转化为了如何让进程之间通信起来。 

如何让进程完成通信

        然后上面知识基本的是什么为什么, 现在我们要谈论的细节就是, 通信是有成本的, 这个成本主要体现在要打破进程间的独立性。

        而又因为我们进程间是独立的, 所以又不能过度的破坏进程间的独立性。 

        所以, 怎么办才能让进程间完成通信呢?

        首先我们必须知道, 进程间通信的本质——必须让不同的进程看到同一份“资源"

        其次, 有一个"资源”特定形式的内存空间——并且进程一个往里写, 一个往里读——什么意思呢, 怎么理解这个“资源”呢? 就类似于电视剧里面的绑匪, 电视剧里面的绑匪会与被绑架者的家属约定一个地点, 然后说让家属扔一百万到旁边的垃圾桶。 这个家属呢, 扔完钱就可以走了, 之后绑匪就去取这个钱。 这个故事里面的家属和绑匪, 就是两个进程, 而这个垃圾桶就是资源。 当家属将钱放到垃圾桶, 就类似于一个进程向资源中写入, 当绑匪拿到钱, 就类似于另一个进程从资源里获取资源

        那么, 这个资源是谁提供呢? ——一般是由操作系统提供为什么不是我们两个进程中的一个呢? 因为假如是一个进程提供资源, 那么这个资源就暴露了, 进程也就破坏了进程本身的独立性。 所以这个资源由操作系统提供, 操作系统就是第三方空间。

        我们进程访问这个空间, 进程通信, 本质就是访问操作系统!!!——因为这个空间是由操作系统提供的, 因为进程是用户启动的, 所以进程代表的就是用户, 那么问题来了, 我们说过, 群众之间有坏人, 而操作系统并不相信用户。 所以呢, 我们的资源从创建, 到使用, 到终止(释放)这个过程, 并不允许我们的进程直接访问资源, 而必须使用对应的系统调用!!!

        而我们所谓的系统调用, 从底层设计, 到接口设计,都是由操作系统设计。 一般的操作系统, 会有一个独立的通信模块——隶属于文件系统。 ——这个模块就叫做IPC通信模块。通信模块一开始是没有的, 是后来人们发现进程间通信越来越重要, 才设计出来的模块, 而且通信模块的设计有许多大佬的参与, 并且由大佬们挂到了文件系统上面, 那么我们要知道, 在设计操作系统的时候, 从底层原理设计上, 到通信模块上, 有许多家都在进程设计不同的操作系统。 那么这个时候就要定制标准。——也就是说, 从使用到原理上, 我们要定制一个大家都要遵守的标准, 定好之后, 我们大家都是用同一套规则, 这样linux的标准就是比较完善的了。 ——其实说这么多, 这里要谈的就是, 进程是有标准的。我们可以观察一个现象, 就是最近许多的操作系统出世, 比如说华为的鸿蒙, 小米的澎湃, 这些新的操作系统, 和我们传统的使用的安卓, windows并不是同一款操作系统。 那么, 就是这不同的操作系统之间却能够相互之间进行数据间的通信!!!换句话说, 我们的这些设备连底层的硬件——网卡都不一样, 但是却能够通信。 ——这其实就已经很能够说明问题了!

        那么, 这个标准是什么呢? 这个标准有两个——system V(本机内部) && posix(网络通信)

        ps:本篇内容不谈论这两个的任何一个, 而是要谈论另一个通信——管道。——光管道的内容就够友友们喝一壶的, 内容很多, 耐心观看。

 管道

 认识管道

        当我们的进程没有上面谈论的两种标准的时候, 是如何进行通信的呢? ——其实就是使用的一种基于文件的通信方式——管道。

        首先我们知道, 一个文件是能够被一个进程打开的, 但是问题是:一个文件能否被多个进程打开呢?——答案是可以的, 那么既然我们的文件能够被多个进程所打开, 那么只要我们的一个进程向文件里面写, 一个进程向文件里面读。 ——其实就是一个进程向文件里面刷新数据, 刷新到磁盘, 然后另一个进程向文件里面读, 就完成了进程的通信。 

        但是这种方式因为是将我们的数据写到外设里面, 所以这个就一定会伴随着很多很多的效率问题。

        现在来学习一下管道, 如下图, 就是管道的一个应用例子。 其中wc就是统计行记录, 而我们的who是打印所有用户的行。

        这里面的who, 我们知道的是它是一个指令, 它其实在运行的时候就已经变成了一个进程。 有了who这个进程之后, 还有一个叫做wc, 这两个进程中间就是用管道连接

文件原理

为了方便讲解原理, 这里我们先将图放出来, 以便讲解:

友友们可能不懂这张图, 但是我会慢慢讲解, 不急。

  •  我们知道, 一个进程, 打开的时候, 就会默认打开三个文件输入输出流, 分别是stdin, stdout, stderror。并且, 这里的stdout, stderror其实是只打开了一个显示器文件, 这里为了更加直观, 博主将他们画成了三个。 其实是两个
  • file_struct 和 文件描述符数组, 指向我们的文件struct file, 然后每一个数组元素天然就具备了下标, 这个下标就是我们返回上层时的fd(文件描述符)。
  • 然后创建一个新的文件, 我们就要先将磁盘中的数据加载到内存中
  • 那么,就要创建一个新的struct file
  • 同时, 我们说过, 我们每一个文件都要提供是哪个核心的东西, 第一个是文件的详细属性——inode。第二个是能够访问底层不同的对应的操作集, 方法集——file operators(这个东西是文件里面的那个函数指针、指向了不同的底层硬件的各种使用方法。——类似于多态, 实现了一切皆文件)。第三个就是文件页缓冲区。
  • 我们要打开的文件的属性会保存在inode里面。文件的数据会保存在文件的页缓冲区。然后呢, 如果我们数据为脏,就会将数据刷新回磁盘里面。这个过程就是落盘的过程。——什么意思, 就是说, 我们的磁盘的文件打开后, 一定要先将文件的数据保存到文件页缓冲区, 然后才能够对文件进行写入或者修改。 然后呢, 只要我们对内存中的数据进行修改或者写入, 那么就说这个数据为脏, 那么就要将修改或者写入后的数据重新刷会磁盘。——这个过程, 就叫做落盘的过程!!!                                                                但是, 如果今天我们想要读取一个文件, 我们不写, 只读, 读取文件, 也照样要把磁盘当中数据加载到内存中。 也就是说, 在文件操作上, 无论读写, 都要先将数据加载到内存当中。 

         知道了上面的知识之后, 我们考虑一个问题, 就是我们如果磁盘中, 根本没有文件, 但是我们今天要打开它。也就是说, 我们今天打开一个文件, 这个文件在文件中有他的inode, file_operators, 文件页缓冲区。 但是呢, 在我们的磁盘中并没有这个文件时, 这个文件真正的变成了一个内存级文件, 请问, 这个可不可行?——现在我们就来谈一谈这种文件的可行性。

管道原理

单进程内存级文件

        首先先说结论, 其实是有可行性的, 操作系统内部有非常非常多的内存级文件他们只需要在内存中用起来即可, 不需要在磁盘中存在

        原本的我们的文件的file_operators保存的是硬件层面的接口, 并且操作系统要让内存中的数据向磁盘中进行刷新。 如今呢, 我们的file_operators直接保存软件层面的接口, 也就是内存级层面的接口了, 操作系统也不需要让内存中的数据向磁盘中进行刷新了。 

        其实我们的管道本质上就是上面的内存级文件。 

        内存级文件的原理,或者说是管道的管理其实和磁盘文件级文件的管理是有相同的地方的。 

        上图的左边部分,我们知道, 是属于进程的部分。 而内存级文件和磁盘级文件的不同是属于文件系统的部分。 所以显然左边部分和上面学习的文件原理是一样的。 那么我们区别就是右边部分。 右边部分的区别是我们没有磁盘文件向文件缓冲区写入数据了。 而改成了我们的进程拿到file_operators,使用file_operators向文件缓冲区中写入数据

带有父子进程的内存级文件

当我们的一个进程创建出一个子进程, 那么就要创建PCB, 地址空间, 文件描述符等等。 

        

        但是, 我们的文件struct file需不需要拷贝给子进程呢?——但是不需要, 因为要知道, 我们的文件, 是属于系统的, 是有系统打开的, 并不是属于这个进程的。 我们进程与文件(这里的文件指的是内存里面的文件struct file)之类的关系, 并不是从属的关系。而是关联的关系, 我们的进程所有的file_struct 可以找到struct file, 可以使用struct file的file_operators接口, 可以修改数据到内存, 但也仅此而已!!!而且, 我们的操作系统也说过——操作系统的管理一般分为:进程管理, 驱动管理, 内存管理, 文件管理。 可见, 进程和文件之间是并列的关系, 并不是从属的关系。

        那么, 再思考一个问题, 为什么我们的文件描述符表也要有呢?——因为文件描述符表是我们当前进程打开文件的列表——而父进程和子进程并不是同一个进程, 而且又有相同的内容,所以子进程就要拷贝父进程一份file_struct。——这也就是为什么我们的父进程打印, 我们的子进程也打印, 但是两个会同时向我们的同一个终端打印的原因。

管道的形成

        进程间通信, 因为进程间具有独立性, 所以两个进程正常情况下不能够进行数据层面的交互的。要是让进程间进行通信, 本质, 也可以说是前提就是务必让不同的进程看到同一份操作系统的资源。 ——如果看不到的话, 就无法通信。 

        如果今天, 我们的进程打开了一个内存级文件, 那么如果这个进程又创建了一个子进程, 这个时候父进程会指向同一个struct_file, 那么如果父进程想要向子进程进行通信, 那么只要父进程将数据写到我们的文件页缓冲区, 然后子进程从文件页缓冲区进行读取, 那么是不是就能够将数据读取到了?就完成进程间的通信了。

        管道的本质也叫做文件!!!管道就是文件, 只不过管道文件不是我们理解的磁盘文件。 

        但是这里有一个问题, 就是当我们的父子进程进行通信的时候, 如果一方不下心将文件关掉了, 那么会不会影响另一个呢?——答案是不会的, 因为我们的struct_file里面包含了一个int cnt的引用计数, 只要当我们有一个文件描述符指向struct_file的时候, 对应的struct_file就会加加。 也就是说, 父子进程都打开这个文件的时候, 这个文件的应用技术就一定会大于等于2!所以一个进程关掉文件后不会影响另一个进程。

        另一个问题就是, 我们说,我们打开一个文件的时候, 设置的权限是只读"r",  这就造成了一个问题。 我们说我们要一个读一个写, 现在我们两个文件都只能读。 那么我们能不能将文件设置成可读可写呢?——答案是不能, 因为, 我们的管道在设计的时候, 并没有设计成可以支持读写。——所以, 这就导致, 我们的父进程再打开子进程的时候, 不能这么简单的打开了。

        我们的父进程在系统中打开管道文件的时候, 并不只是把文件单方面的打开或者读或写, 而是打开这个管道文件的时候, 对于这个管道文件,既以读的方式打开, 又以写的方式打开。

然后父进程再创建子进程, 子进程拷贝文件描述符表。 ——所以, 父进程和子进程都有对应的读写段指向同一个文件。        

然后我们就要结合具体场景, 确定我们的两个进程到底是读, 还是到底是写。 ——这就要求我们的父子进程分别关闭一个读写段, 形成一个单向的通信信道。 ——比如父进程关闭读, 子进程关闭写。 父进程用来写入, 子进程用来读取。 ——又比如父进程关闭写, 子进程关闭度。 父进程用来读取, 子进程用来写入。 

        那么我们站在内核的角度, 管道的本质是什么呢。

  • 首先就是两个文件描述符                                                                                                        
  • 这个然后两个进程的文件描述符的两个fd都指向同一个文件。但是对于我们的操作系统来说, 我们如果想要再打开一次这个文件, 还是需要再创建一个struct file——因为这两个文件的读写方式不一样, 而又因为我们的每个文件都有我们的读写位置, 如果我们两个fd同时指向一个struct file, 那么很容易就出现问题。 所以, 操作系统要创建两个struct file。 但是!——这两个文件的inode, file_operators, 文件缓冲区是一样的。 这其实也可以读,也可以写。 就比如我们的r + w, 但是这就有一个问题, 因为我们的一个struct file里面有自己的读写位置。 并且这个位置, 也可以说是偏移量是欸一的, 那么当我们向文件中写入数据后, 如果想读这些数据, 我们是读不出来的。 因为我们的读写位置在写的时候已经发生了变化了。 我们读数据是在刚刚写入的地方读的。 除非我们写入数据后, 又用rewind吧读写的位置回归到最开始了!

        现在的情况是, 我们的父进程和子进程都有读有写。 那么这个缓冲区里面的数据就不知道是谁的了。 所以我们的设计者就规定——我们只想让父子进行单向通信。 然后由用户规定谁给谁通信。

        我们这里假如规定成子进程写入, 父进程读取。

        所以, 那么我们上面的父子进程就要各自关闭一个文件描述符。

        

        以上, 就是管道通信的本质。 而之所以叫做管道, 是因为它只能进行单向通信!——而为什么是单向通信的, 第一是因为它是基于文件通信的, 第二是因为设计者为了图简单。 ——所以就有了管道的名字。 如果我们要进行双向通信呢?——就用多个管道。

        上面讲的是父子进程层面的, 但是我们如果两个进程没有任何关系, 可以使用我们刚刚讲的原理进行通信吗?不能!——这里的管道的形成, 必须是有血缘关系的!!!——比如爷孙, 比如父子。

——以上就是本篇的全部内容, 本篇内容到此就结束啦, 感谢友友的阅读, 下面是本节的笔记, 和正文几乎一样的, 觉得本节内容有用的话可以保存方便查阅哦

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

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

相关文章

【C语言】归并排序递归和非递归——动图演示

目录 一、归并排序思想1.1 基本思想1.2 大体思路 二、实现归并排序(递归)三、实现归并排序(非递归)3.1 实现思路:3.2 越界处理3.3 时间复杂度和空间复杂度 总结 一、归并排序思想 1.1 基本思想 归并排序(M…

RTMP和WebRTC使用场景有哪些差别?

省流版先说结论 直播领域,RTMP和WebRTC各有优势。如果直播场景对延迟有一定要求,但更注重稳定性和兼容性,那么RTMP可能是一个更好的选择。如果直播场景需要极低的延迟,并且用户主要在浏览器环境下进行观看和互动,那么…

Leangoo敏捷工具在缺陷跟踪(BUG)管理中的高效应用

在开发过程中,缺陷(BUG)管理一直是项目管理中的一个关键环节。及时发现并修复BUG,不仅能够提高产品质量,还能有效提升团队的工作效率和用户满意度。 在敏捷开发中,快速迭代和频繁交付的特点使得缺陷管理的…

Servlet的特性(一)

Servlet的主要用途: 接受、处理来自浏览器端(BS架构中的B端)的请求和用户输入 响应来自数据库或者服务端(BS架构中的S端)产生的数据到浏览器端,动态构建网页。 手动实现Servlet小程序 实现步骤 自定义一个类型,实现Servlet接口或者继承Ht…

Spring Boot 集成 Redisson 实现消息队列

包含组件内容 RedisQueue:消息队列监听标识RedisQueueInit:Redis队列监听器RedisQueueListener:Redis消息队列监听实现RedisQueueService:Redis消息队列服务工具 代码实现 RedisQueue import java.lang.annotation.ElementTyp…

GD32E230 RTC报警中断功能使用

GD32E230 RTC报警中断使用 GD32E230 RTC时钟源有3个,一个是内部RC振动器产生的40KHz作为时钟源,或者是有外部32768Hz晶振.,或者外部高速时钟晶振分频作为时钟源。 🔖个人认为最难理解难点的就是有关RTC时钟异步预分频和同步预分频的计算。在对…

C++第二节入门 - 缺省参数和函数重载

一、缺省参数 1、概念 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。 在调用该函数的时候&#xff0c;如果没有指定实参则采用该形参的缺省值&#xff0c;否则使用指定的实参&#xff01; #include<iostream> using namespace std;void Func(int a 0) {c…

2024 水博会,国信华源登场,数智创新助力水利高质量发展

9月4日-6日&#xff0c;由中国水利学会和中国水利工程协会共同主办的2024中国水博览会暨第十九届中国&#xff08;国际&#xff09;水务创新技术交流会在重庆国际博览中心召开。 本次水博会以“展水利前沿新技术 览新质生产力场景”为主题&#xff0c;国信华源携最新智能监测预…

【佳学基因检测】如何升级一个不再维护的软件包中的PHP代码?

如何升级一个不再维护的软件包中的PHP代码&#xff1f; 为什么要升级一个不再维护但是仍在使用的软件包中的PHP代码&#xff1f; 升级一个不再维护但仍在使用的软件包中的 PHP 代码是一个复杂但重要的过程。虽然这些软件包可能已经不再活跃地维护或更新&#xff0c;但升级其代…

通信工程学习:什么是ATM异步转移模式

ATM&#xff1a;异步转移模式 ATM&#xff1a;Asynchronous Transfer Mode&#xff08;异步转移模式&#xff09;是一种先进的通信技术&#xff0c;它采用固定长度的信元&#xff08;Cell&#xff09;作为信息传输、复用、交换及处理的基本单位&#xff0c;并通过异步时分复用的…

挖矿木马-Linux

目录 介绍步骤 介绍 1、挖矿木马靶机中切换至root用户执行/root目录下的start.sh和attack.sh 2、题目服务器中包含两个应用场景&#xff0c;redis服务和hpMyAdmin服务&#xff0c;黑客分别通过两场景进行入侵&#xff0c;入侵与后续利用线路路如下&#xff1a; redis服务&…

Tomcat Request Cookie 丢失问题

优质博文&#xff1a;IT-BLOG-CN 一、问题描述 生产环境偶尔(涉及到多线程处理)出现"前端传递Cookie为空"的告警&#xff0c;导致前端请求丢失&#xff0c;出现请求失败问题。告警内容如下 前端传递Cookie为空 告警内容&#xff1a;服务端获取request Cookie为空&…

2024网安周今日开幕,亚信安全亮相30城

2024年国家网络安全宣传周今天在广州拉开帷幕。今年网安周继续以“网络安全为人民&#xff0c;网络安全靠人民”为主题。2024年国家网络安全宣传周涵盖了1场开幕式、1场高峰论坛、5个重要活动、15场分论坛/座谈会/闭门会、6个主题日活动和网络安全“六进”活动。亚信安全出席20…

每日一练:螺旋矩阵

一、题目要求 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a; 输入&#xff1a;ma…

Java | Leetcode Java题解之第396题旋转函数

题目&#xff1a; 题解&#xff1a; class Solution {public int maxRotateFunction(int[] nums) {int f 0, n nums.length, numSum Arrays.stream(nums).sum();for (int i 0; i < n; i) {f i * nums[i];}int res f;for (int i n - 1; i > 0; i--) {f numSum - …

NISP 一级 | 3.1 网络基础知识

关注这个证书的其他相关笔记&#xff1a;NISP 一级 —— 考证笔记合集-CSDN博客 0x01&#xff1a;Internet 和 TCP/IP 协议 因特网&#xff08;Internet&#xff09;通过 TCP/IP 协议将遍布在全世界各地的计算机互联&#xff0c;从而形成超级计算机网络。因特网为用户提供了非…

【50 Pandas+Pyecharts | 暑期档电影票房数据分析可视化】

文章目录 &#x1f3f3;️‍&#x1f308; 1. 导入模块&#x1f3f3;️‍&#x1f308; 2. Pandas数据处理2.1 读取数据2.2 提取电影名称 &#x1f3f3;️‍&#x1f308; 3. Pyecharts数据可视化3.1 电影总票房排行3.2 各电影票房占比3.3 2023中国各省地区大学数量分布3.4 《抓…

浅谈产线工控安全,产线工控安全的有效方案

随着工业4.0的发展&#xff0c;产线日益智能化&#xff0c;生产网已经发展成一个组网的计算机环境&#xff0c;虽然都进行了隔离&#xff0c;但仍需和外部进行数据交互&#xff0c;导致有病毒入侵可能。 产线工控安全事件不断 深信达MCK主机加固方案&#xff0c;针对产线工控…

工业无人机性能参数特点!!!

一、基本性能参数 动力系统&#xff1a;工业无人机多采用电动或油动动力系统&#xff0c;以提供足够的推力和续航能力。电动无人机通常具有较低的噪音和振动&#xff0c;适合城市或近距离作业&#xff1b;而油动无人机则具有更长的续航时间和更大的载重能力&#xff0c;适合远…

安科瑞Acrel-1000DP分布式光伏监控系统平台的设计与应用-安科瑞 蒋静

针对用户新能源接入后存在安全隐患、缺少有效监控、发电效率无法保证、收益计算困难、运行维护效率低等通点&#xff0c;提出的Acrel-1000DP分布式光伏监控系统平台&#xff0c;对整个用户电站全面监控&#xff0c;为用户实现降低能源使用成本、减轻变压器负载、余电上网&#…