【Linux】进程间通信(一)---- 匿名管道

【Linux】进程间通信(一)---- 匿名管道

  • 一.序
    • 1什么是进程间通信
    • 2.进程间通信的标准
    • 3.为什么需要进程通信
  • 二.匿名管道
    • 1.原理
    • 2.使用
    • 3.四种情况
    • 4.五个特点

一.序

1什么是进程间通信

进程间通信
通信我们大致知道是啥,就是互相传递信息
那进程间通信,就是进程间相互传递信息了

我们知道信息就是就是数据

我们都知道进程具有独立性
所以我们想要让进程中的一个,将信息直接传递给另一个进程
虽然从理论上讲确实可以,但这样无疑是破坏了进程的独立性

所以操作系统会给在内存中开辟一个公共空间
让这两个进程来进行通信

但是我们想想
进程访问这个空间,进行通信,本质就是访问操作系统
进程对于系统来说就是用户,因为进程是用户来控制的

我们曾经多次提到:操作系统是不会信任用户的
所以操作系统从开辟公共内存到进程的相互通信,都是通过调用系统自己设计的接口来进行的

所以:
一般操作系统会有一个独立的通信模块,隶属于文件系统,叫做IPC通信模块

2.进程间通信的标准

我们知道在计算机行业中,**标准是很重要的,**就像5G的行业标准是华为制定的。

所以为了让不同计算机的不同操作系统的不同文件系统,都能进行通信,所以进程间的通信标准是很重要的。
进程间通信的定制标准system Vposix

3.为什么需要进程通信

1.基本数据
2.发送命令
3.某种协同
4.通知

基于这几种需求,所以创造出了进程通信

其实以前进程间是不会进行通信的
但是人们发现进程通信还挺有必要的
所以进程间通信的产生是历史的必然

二.匿名管道

这个匿名管道就是进程间通信的一种方式,但是也有局限

现在先为大伙带来原理,再带大家来使用

1.原理

这里就得用到博主曾经在FD的图了
在这里插入图片描述
这个是以前在讲文件FD时用到的图

那如果我们这个时候fork一个子进程会怎么样呢

我们知道子进程fork的时候,子进程会获得与父进程相同的虚拟地址空间的副本,使子进程拥有与父进程相同的代码、数据和堆栈。

这个时候看看上面的图:
我们知道这个struct taskstruct files_struct

所以他们也会被子进程进行复制

在这里插入图片描述
我们知道左边的部分是这样被子进程复制的

那么问题来了,右边的打开的文件需不需要被复制呢

在这里插入图片描述

这个答案肯定是否定的,因为右边两个被子进程复制走
因为他们都是父进程的一部分,但是打开的文件就不一样了
因为打开的文件和进程是平级的,并不是与进程的一部分

所以是这样的
在这里插入图片描述

所以,利用这个特性,我们就能来创建我们的匿名管道了

在这里插入图片描述

我们打开一个buffer缓冲区(实际上就是一个内存级文件)

这个时候如果fork一下呢?

在这里插入图片描述

就会变成这样

这个时候其实我们就能发现了,这两个进程已经能进行双向通信了

但是看看我们这个叫啥
匿名管道,管道两个字就注定了,它只进不出

因为如果子进程和父进程都同时进行读和写的话
谁能保证父进程写完,会被父进程读走呢?
所以为了确保通信的稳定性和便于实现性
所以这里就要:
关掉父进程的读或者子进程的写
或者关掉父进程的写或者子进程的读

让它变成单向通信。

在这里插入图片描述
在这里插入图片描述

这里就是匿名管道的原理了

2.使用

这里我们已经把管道的原理给讲明白了
接下来就是使用了

之前提过:操作系统是不会信任用户的
所以操作系统从开辟公共内存到进程的相互通信,都是通过调用系统自己设计的接口来进行的

所以这里就要解释接口了

int pipe(int pipefd[2]);

在这里插入图片描述

pipe是起这个作用的

接下来就带大伙来试一下匿名管道通信

#include<unistd.h>
#include<iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <cstdio>
#include <cerrno>
using namespace std;
void child_write(int pipefd[2])
{const char * buffer="my dad";int cnt=2;while(cnt--){write(pipefd[1],buffer,sizeof(buffer));cout<<"write success"<<endl;}}
void father_read(int pipefd[2])
{char buffer[1024];while (true){ssize_t bytesRead = read(pipefd[0], buffer, sizeof(buffer) - 1); // 留出一个字节存放字符串结束符if (bytesRead == 0)break;buffer[bytesRead] = '\0'; // 手动添加字符串结束符cout << buffer << endl;}
}
int main()
{int pipefd[2];if(pipe(pipefd)==-1){perror("pipe失败");return 0;}pid_t id=fork();if (id < 0) {perror("fork");return 1;} // 子进程else if(id == 0) {//这里就实现子进程写,父进程读把close(pipefd[0]);//子进程读child_write(pipefd);//写完,关闭通道close(pipefd[1]);} // 父进程else {close(pipefd[1]);//父进程写father_read(pipefd);}//读完,关闭通道close(pipefd[0]);//回收子进程int status;if(wait(&status)>0)cout<<"wait success\n"<<endl;}

在这里插入图片描述

这样就完成了通信

3.四种情况

管道的四种情况:
1.读写端正常,管道如果为空,读端就要阻塞
管道没有接受到数据,读端就会一直等待数据

2.读写端正常,管道如果满,写端就要阻塞
管道满了,读端没有读数据,数据就堵在管道了,写端无法继续写

3.写端退出,读端正常,读端读到0,不会阻塞
这是因为读端正常,写端没数据了,这个时候代表是正常读写完成。

4.读端退出,写端正常,会把写端关闭
因为操作系统不让做一些浪费性能的事情,已经没有人读取你的数据了,那你就没有继续写的必要了,系统会自己把写端关闭

4.五个特点

匿名管道的五个特点;

1.管道本质是内存级文件,寿命周期是进程
这个是肯定的,管道本来就是为了通信存在的,父子进程通信完毕,自然也就关闭了

2.管道只能单向通信
这个最前面我们也提到过

3.具有血缘关系(常见的是父子)的进行进程间通信
因为我们利用的就是父子进程fork后复制files struct的原理
其实爷孙进程也可以用,只不过常见的是用在父子而已

4.管道是面向字节流的
这个还不太好解释,之后的博客会有解释

5.父子进程会进程协同,同步与互斥的
这个也不太好解释,之后博客也会进行解释

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

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

相关文章

【软考】设计模式之组合模式

目录 1. 说明2. 应用场景3. 结构图4. 构成5. 优点6. 缺点7. java示例 1. 说明 1.将对象组合成树型结构以表示“部分-整体”的层次结构。2.Composite使得用户对单个对象和组合对象的使用具有一致性。3.组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式 …

德昂信息-Wyn助力构建HR人员信息分析看板

”葡萄城的Wyn商业智能软件产品为德昂信息提供了强大的支持&#xff0c;借助Wyn商业智能软件&#xff0c;可以通过可视化方式展示整个公司的人员信息及其分析看板。“ ——德昂信息技术(北京)有限公司 公司简介 德昂信息技术(北京)有限公司&#xff08;以下简称德昂信息&…

STM32_HAL_TIM_通用计时器_实现计时

项目思路 1使用定时器计数每秒一次 2使用一个变量记录定时器响应多少次 3使用UART将记录的次数发出 1STM32Cude设置 1配置时钟源 2打开UART 3打开TIM2 3.1界面介绍 3.2选项介绍 Slave Mode&#xff08;从模式&#xff09;&#xff1a;当设备被设置为从模式时&#xff0c…

计算机组成原理(超详解!!) 第八节 总线系统

1.总线的概念和结构形态 1.总线&#xff08;BUS&#xff09;的基本概念 是构成计算机系统的互联机构&#xff0c;是多个系统功能部件&#xff08;运算器、控制器、存储器、输入/输出设备&#xff09;之间进行数据传送的公共通路。 由传输信息的电路和管理信息传输的协议组成…

数据结构【顺序表】

文章目录 1.顺序表的概念线性表物理结构逻辑结构 2.顺序表的分类2.1静态顺序表2.2动态顺序表 3.顺序表接口的实现头文件(SQList.h)如下源文件初始化顺序表销毁顺序表插入扩容尾插头插 封装扩容函数删除尾删头删 查找元素在指定位置前插入数据情况一(指定的位置不是首元素)情况二…

【机器学习】逻辑回归:智能垃圾邮件分类实例

逻辑回归&#xff1a;智能垃圾邮件分类的利器 一、引言二、逻辑回归概述三、垃圾邮件分类实例数据准备特征选择与建模 四、总结与展望 一、引言 随着互联网的迅猛发展&#xff0c;电子邮件已成为人们日常生活和工作中不可或缺的一部分。然而&#xff0c;与此同时&#xff0c;垃…

[蓝桥杯]真题讲解:合并数列(双指针+贪心)

[蓝桥杯]真题讲解&#xff1a;班级活动&#xff08;贪心&#xff09; 一、视频讲解二、正解代码1、C2、python33、Java 一、视频讲解 [蓝桥杯]真题讲解&#xff1a;合并数列&#xff08;双指针贪心&#xff09; 二、正解代码 1、C #include<bits/stdc.h> #define in…

k8s 网络组件详细 介绍

目录 一 k8s 有哪些网络组件 二 k8s 网络概念 1&#xff0c; k8s 三种网络 2&#xff0c;K8S 中 Pod 网络通信 2.1 Pod 内容器与容器之间的通信 2.2 同一个 Node 内 Pod 之间的通信 2.3 不同 Node 上 Pod 之间的通信 三 Flannel 网络组件 1&#xff0c;Flannel …

K8s源码分析(一)-K8s调度框架及调度器初始化介绍

本文首发在个人博客上&#xff0c;欢迎来踩&#xff01; 文章目录 调度框架介绍K8s scheduler 介绍K8s scheduler的初始化Cobra介绍K8s scheduler中初始化的源代码解析 调度框架介绍 这是官方对于v1.27调度框架的介绍文档&#xff1a;https://v1-27.docs.kubernetes.io/docs/…

使用vue3+ts+vite从零开始搭建bolg(五):layout(持续更新中)

五、layout搭建 5.1静态搭建 在src下创建如图文件夹 这里用logo举例&#xff0c;在scripts里export <script lang"ts">export default {name: Logo,}</script> 然后在layout里引入 //引入左侧菜单顶部用户信息 import Logo from ./logo/index.vue 接…

Spring AOP(概念,使用)

目录 Spring AOPAOP是什么什么是Spring AOPAOP实际开发流程1. 引入依赖2. 编写AOP程序 Spring AOP详解Spring AOP中的核心概念Spring AOP的通知类型六种类型PointCutOrder(切面优先级) Spring AOP AOP是什么 Aspect Oriented Programminig(面向切面编程)切面指的是某一类特定…

“Linux”目录结构and配置网络

了解完命令格式和vi、vim编辑器后&#xff0c;我们来认识一下目录的结构&#xff1a; 一、目录 &#xff08;1&#xff09;目录的特点 windows特点&#xff1a; Windows中有C、D、E盘&#xff0c;每个都是一个根系统 Linux特点&#xff1a; linux中只有一个根&#xff08;单…

C++auto关键字、范围for循环

一、auto关键字 1.1auto简介 在早期C/C中auto的含义是&#xff1a;使用auto修饰的变量&#xff0c;是具有自动存储器的局部变量。 C11中&#xff0c;标准委员会赋予了auto全新的含义即&#xff1a;auto不再是一个存储类型指示符&#xff0c;而是作为一个新的类型指示符来指示编…

记录用python转换headers

转换前 转换后效果 代码如下。注意需要在控制台切换到content.txt所在位置&#xff0c;不然运行代码会报file not found错误 # 假设txt文件内容如下 txt open(content.txt).read()# 使用splitlines()方法将txt内容分割为行&#xff0c;然后使用json.loads()方法将每一行转换为…

每日两题 / 437. 路径总和 III 105. 从前序与中序遍历序列构造二叉树(LeetCode热题100)

437. 路径总和 III - 力扣&#xff08;LeetCode&#xff09; 前序遍历时&#xff0c;维护当前路径&#xff08;根节点开始&#xff09;的路径和&#xff0c;同时记录路径上每个节点的路径和 假设当前路径和为cur&#xff0c;那么ans 路径和(cur - target)的出现次数 /*** D…

【吊打面试官系列】Java高并发篇 - 多线程的价值?

大家好&#xff0c;我是锋哥。今天分享关于 【多线程的价值&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 多线程的价值&#xff1f; 1、发挥多核 CPU 的优势 多线程&#xff0c;可以真正发挥出多核 CPU 的优势来&#xff0c;达到充分利用 CPU 的目的&#…

Linux学习笔记(Socket)

Linux-Socket 1、基础知识2、服务端3、客户端4、读写操作4.1、读写函数4.2、阻塞IO和非阻塞IO 5、例程 1、基础知识 socket用于计算机之间的网络通信&#xff0c;无论是构建服务器还是客户端&#xff0c;我们仅需要三个信息&#xff0c;服务器的ip地址&#xff0c;对应进程的端…

openlayers 热力图 天地图

openlayers 实现热力图 样式可调 在https://blog.csdn.net/qq_36287830/article/details/131844745?spm1001.2014.3001.5501基础上改进来的 关键代码 如果你有数据可以不使用for循环 var blurInput document.getElementById("blur");var rediusInput document.g…

PyQt5编写的一个简易图像处理软件

文章目录 1. 简介2. 准备工作3. 主界面设计4. 功能构建5. 总结 1. 简介 通过编写简易图像处理软件&#xff0c;你可以学习如何使用 PyQt5 构建用户界面&#xff0c;以及如何与用户交互。同时&#xff0c;你还可以学习图像处理技术&#xff0c;如图像读取、傅里叶变换、滤波、增…

【NR学习一】NR中的带宽、子载波间隔、PRB数量、FFT点数与采样率之间的关系

NR中的带宽、子载波间隔、PRB数量、FFT点数与采样率之间的运算关系 在5G NR&#xff08;New Radio&#xff09;系统设计中&#xff0c;带宽&#xff08;Bandwidth&#xff09;、子载波间隔&#xff08;Subcarrier Spacing, SCS&#xff09;、资源块&#xff08;Resource Block…