当管道运算符遇上无限可能:探索数据流的奇妙之旅

文章目录

  • 序言
  • 目的
  • 进程间通信的理解
  • 进程间通信的发展历史
  • 管道创建
  • 验证管道的大小
  • 管道的4种情况
  • 管道的5种特征

序言

在这里插入图片描述
通过该命令计算了在当前路径下一共有多少个文件夹的任务

进程虽然有独立性,但是进程并不孤僻,他们之间也会相互进行协作共同完成一件事
这个前提是他们之间的信息能传递(进程间通信)

目的

数据传输:进程将数据发送给另一个进程
资源共享:进程间共享同样的资源
通知事件:一个进程向另一个或一组进程发送信息,通知他们完成了某事(如子进程终止通知父进程)
进程控制:有些进程希望完全控制另一个进程(如Debug进程),此时控制进程就希望能够
拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变

进程间通信的理解

例如

爸妈吵架,分房睡觉了,互相不说话,相互独立.但是又要交流,所以我成为了他们交流的枢纽
爸妈就是两个进程, 我就是OS
我妈让我叫我爸吃饭
我爸说不吃顺便告诉我妈 就相当于进程间通信
进程间通信本质:让不同的进程看到同一份资源(比如爸妈吵架交流,我还没回家,他们就不相往来)
这一份资源,不能由俩进程单独提供,但是可以申请(比如,我爸可以叫我回来)
通常由OS提供

进程间通信的发展历史

一个程序被加载成进程就有了缓冲区,所以早期设置进程间通信的时候就想着复用以前的代码,所以有了进程间通信的几种方式,其中一种就是管道,还有

system V IPC, POSIX IPC
system V—进程间本地通信
POSIX – 跨网络,实现跨主机通信

管道创建

在这里插入图片描述

在这里插入图片描述在这一步,父进程创建子进程后,子进程的files_struct也有内容指向管道文件

在这里插入图片描述然后父进程关闭读端,子进程关闭写端
这样就创建了一个管道
那么,具体情况是怎样的呢?

当一个进程被创建时:
在这里插入图片描述当创建子进程后,文件描述符表也会浅拷贝给子进程
而文件部分不会拷贝给子进程
所以父子进程的打印打印信息都能在屏幕上显示

这个文件页缓冲区:

就是管道
父进程向子进程发送消息
管道文件是纯内存的文件
这个文件不需要向磁盘写入,也不需要路径和文件名
所以叫做匿名管道

在这里插入图片描述
如何让不同的进程看到同一份资源文件管道?
创建子进程时,复用同一套代码,让父子进程读到同一个文件

在这里插入图片描述总结上图就是:
在这里插入图片描述
代码创建管道:

#include<iostream>
#include<unistd.h>
#include<cassert>
#include<sys/types.h>
#include<sys/wait.h>
#include<cstring>
#define MAX 1024using namespace std;
int main()
{//第一步,建立管道int pipefd[2] = {0};int n = pipe(pipefd);assert(n == 0);//debug下才存在,在release模式下这条语句会不存在,这样导致的问题是,n在后续的release中会未被使用(void)n;//这样会导致一些编译器的报错,所以加此语句的目的是防止这样的报错发生cout<<"pipe[0]:"<<pipefd[0]<<",pipe[1]"<<pipefd[1]<<endl;//第二步,创建子进程pid_t id = fork();if(id<0){perror("fork");return 1;}//第三步,形成单向通信的管道,子写,父读//父子进程关闭不需要的fd,即可形成单行通信的管道//形成单行管道后,可以不用手动关闭,因为进程退出后会自动释放当前进程对应的文件描述符表//所以手动关闭不关闭看情况,这边是不需要手动关闭if(id == 0){//child 子进程写入close(pipefd[0]);//向管道写入信息,只有写入,没有打印int cnt = 0;while(true){// char c = 'a';// write(pipefd[1],&c,1);// cout<<"write  :" << ++cnt <<endl;cnt++;char message[MAX];snprintf(message,sizeof(message),"i'm child,my pid is %d , cnt %d",getpid(),cnt);//snprintf,向指定的对象中写入,写入多少个字节,写入什么内容...write(pipefd[1],message,strlen(message));sleep(1);if(cnt > 3) break;}//close(pipefd[1]);cout << "child close w point" << endl;exit(0);}//father,读取close(pipefd[1]);//用来从管道当中读取char buf[MAX];while(true){ssize_t n = read(pipefd[0],buf,sizeof(buf)-1);//减一的目的是万一缓冲区读满了,可以留出空位置来给\0if(n > 0)//读取成功,切返回读取到的字符串的长度{buf[n] = 0;//当做字符串cout << "my pid:"<<getpid()<<",child says:" << buf << "to me!" << endl;//向屏幕打印信息}else if(n == 0){cout << "child is quit, me too!" << endl;break;}sleep(1);cout << "father return val(n): " << n << endl;break;}cout<<"read is closed"<<endl;close(pipefd[0]);sleep(5);int status = 0;pid_t rid = waitpid(id,&status,0);if(rid==id){cout<<"wait successful,child exit sig: "<<(status&0x7F)<<endl;//低7为该进程退出时收到的信号,次低8位退出码}return 0;
}

问题:

1.父进程创建子进程不是数据共享的吗?不是能直接访问吗?为什么要用这样的方式呢?
是能数据共享,能访问,但是不能访问动态的数据,管道可以实现动态数据的父子进程的相互访问,而不用管道只能访问静态的数据
2.利用管道还能实现子进程向父进程数据的写入,这时就不仅限于单独的父进程向子进程的写入数据

运行演示:
在这里插入图片描述

验证管道的大小

验证管道的大小:
在这里插入图片描述

结果:
在这里插入图片描述

进行换算:管道的大小为64字节
在这里插入图片描述

ulimit -a查看管道大小open files指可以打开的文件的个数

在这里插入图片描述

管道大小为8*512/1024==4,并不是64,这边的管道大小并不是实际大小

管道的4种情况

1.如果管道中没有数据了,读段必须进行等待,直到有数据为止
2.管道也有大小,写端不会一直写下去,写满后会阻塞等待,直到等到读端读取数据后(管道有空间),写端才会再继续写入数据

1,2两点对应管道的同步机制(管道特征第二特征)

3.写端关闭,读端一直读,读端会读到read的返回值为0表示读到文件的结尾
在这里插入图片描述
在这里插入图片描述
结果演示:
在这里插入图片描述

4.读端关闭,写端一直写,写入没有意义,OS会杀掉写端进程,进程异常(向目标进程发送13号信号),终止目标进程

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

管道的5种特征

1.匿名管道
在一个进程体系当中,爷孙,兄弟之间都能通过管道来进行通信,常用于父子
2.匿名管道,默认给读写端提供同步机制 这个同步机制体现在下述现象
将代码进行细节处修改

在这里插入图片描述
在这里插入图片描述
读了一部分再写

3.面向字节流-----了解现象即可
读取的时候是按照缓冲区的大小进行读取的,能读多少读多少

4.管道的生命周期是随进程的周期的
当不显示关闭文件,进程退出会有什么影响?
在这里插入图片描述
在这里插入图片描述

可以看到,管道的写端是被关闭的,可是管道也是文件
所以,文件描述符表全称进程文件描述符表是有原因
管道会跟随进程一起关闭

5.管道是单向通信的,半双工通信的一种特殊情况
半双工:

任何时候一个人说,一个人在听

全双工:

你说的时候对方也再说,你说的时候对方还在听,对方也是如此
未来的网络通信都是全双工

实现命令行管道
在这里插入图片描述

像这样的怎么实现呢?

在这里插入图片描述
具体代码,下篇见详情!!

有所帮助希望三连,谢谢支持~~~

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

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

相关文章

嵌入式全栈开发学习笔记---C语言笔试复习大全7(编程题1~8)

目录 1、200&#xff5e;300之间能被3整除的数&#xff0c;5个一行输出&#xff1b; 2、求两个数的最大公约数、最小公倍数&#xff1b; 3、输入十个数&#xff0c;求出平均值&#xff1b; 4、通过编程实现,统计1~n有多少个9&#xff1b; 5、有1、2、3、4个数字&#xff0…

C#简单创建DLL文件并调用

DLL是Dynamic Link Library的缩写&#xff0c;意为动态链接库。动态链接库其实是由编译器将一系列相关的类型编译、链接并封装成一个独立的文件&#xff0c;与对其进行调用的程序分开。这样一个独立的文件相当于程序的一个模块&#xff0c;如果需要对程序进行更新&#xff0c;只…

ESP32-C3第二路串口(非调试)串口打通(1)

1. 概述与引脚复用 《ESP32-C3 系列芯片技术规格书》中提到&#xff0c;ESP32-C3系列芯片中有两路串口。 第1路串口就是常用的调试串口&#xff0c;在笔者使用的ESP32-C3-DevKitC-02开发板中&#xff0c;这一路串口通过CP2102 USB转UART桥芯片与电脑的USB口相连接&#xff0c;…

42 线程池

一种线程使用模式&#xff0c;线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。线程池维护多个线程&#xff0c;等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价&#xff0c;线程池不仅能保证内核的充分利用&#xf…

redis中的双写一致性问题

双写一致性问题 1.先删除缓存或者先修改数据库都可能出现脏数据。 2.删除两次缓存&#xff0c;可以在一定程度上降低脏数据的出现。 3.延时是因为数据库一般采用主从分离&#xff0c;读写分离。延迟一会是让主节点把数据同步到从节点。 1.读写锁保证数据的强一致性 因为一般放…

数据结构------栈的介绍和实现

目录 1.栈的一些初步认识 2.栈的实现 3.相关的函数介绍 &#xff08;1&#xff09;栈的初始化 &#xff08;2&#xff09;栈的销毁 &#xff08;3&#xff09;栈的数据插入 &#xff08;6&#xff09;判断是否为空 &#xff08;7&#xff09;栈的大小 4.栈的实现完整…

【数据结构(邓俊辉)学习笔记】列表01——从向量到列表

文章目录 0.概述1. 从向量到列表1.1 从静态到动态1.2 从向量到列表1.3 从秩到位置1.4 列表 2. 接口2.1 列表节点2.1.1 ADT接口2.1.2 ListNode模板类 2.2 列表2.2.1 ADT接口2.2.2 List模板类 0.概述 学习了向量&#xff0c;再介绍下列表。先介绍下列表里的概念和语义&#xff0…

【HM】DevEco Studio如何使用代码编程AI助手

大家可能都有用过或了解过github copilot插件&#xff0c;确实为我们编码智能、提升开发效率有很大的帮助。推荐两款国产的ai编程插件&#xff0c;分别是华为的CodeArts Snap和阿里的通义灵码。 DevEco 中如何安装通义灵码&#xff1f; 一、下载通义灵码离线安装包 打开官网…

每日OJ题_贪心算法二⑤_力扣870. 优势洗牌(田忌赛马)

目录 力扣870. 优势洗牌&#xff08;田忌赛马&#xff09; 解析代码 力扣870. 优势洗牌&#xff08;田忌赛马&#xff09; 870. 优势洗牌 难度 中等 给定两个长度相等的数组 nums1 和 nums2&#xff0c;nums1 相对于 nums2 的优势可以用满足 nums1[i] > nums2[i] 的索引…

golang学习笔记(内存逃逸分析)

golang的内存逃逸 逃逸分析&#xff08; Escape analysis&#xff09; 是指由编译器决定内存分配的位置&#xff0c; 不需要程序员指定。 函数中申请一个新的对象。 如果分配在栈中&#xff0c; 则函数执行结束可自动将内存回收&#xff1b;如果分配在堆中&#xff0c; 则函数…

解决layui的bug 在layui tree 组件中 禁用选中父节点后自动选中子节点功能

最近做权限管理后台&#xff0c;用了layui tree 组件&#xff0c;发现选中了父节点后&#xff0c;自动选中了子节点。不满足现实业务需求。所以微调了下源代码。 在用树形组件中&#xff0c;在用文档中 tree.setChecked(demoId, [2, 3]); //批量勾选 id 为 2、3 的节点 用这句…

linux 服务器利用阿里网盘API实现文件的上传和下载

文章目录 背景脚本初始化 阿里云盘API工具 aligo安装aligoaligo教程实战parse.py 演示上传文件上传文件夹下载文件下载文件夹 背景 最近在用ubuntu系统做实验&#xff0c;而ubuntu 系统的文件上传和下载操作很麻烦&#xff1b; 于是便打算使用阿里网盘的API 进行文件下载与上传…

腾锐D2000-8 MXM VPX,全国产,可广泛应用于边缘计算网关、入侵检测、VPN、网络监控等等应用领域

腾锐D2000-8 MXM VPX 1. 概述 XMVPX-108 是一款基于飞腾 D2000/8 处理器的低功耗逻辑运算和图形处理 VPX 刀片&#xff0c; 板贴 32GB DDR4 内存&#xff0c;搭载飞腾 X100 套片&#xff0c;满足通用 IO 接口功能。GPU 采用 MXM 小型插卡形式&#xff0c; 搭配 8GB 显卡。提供…

NIO和NIO.2对比

Java NIO (New Input/Output) 是从Java 1.4版本开始引入的一个新的I/O API&#xff0c;用于替代原来的BIO&#xff08;Blocking I/O&#xff09;API。NIO提供了更加灵活和高效的网络通信方式&#xff0c;特别适合于高吞吐量的网络编程。NIO的主要特点是非阻塞模式&#xff0c;它…

3.4 无关、基和维度

这一节是关于子空间的真实大小。对于 m n m\times n mn 的矩阵&#xff0c;它有 n n n 个列&#xff0c;但是它真正的维数不一定为 n n n&#xff0c;维数可以由无关列的个数来得到。列空间的实际维度就是秩 r r r。 无关的概念是用于向量空间中的任意向量 v 1 , . . . ,…

【LAMMPS学习】八、基础知识(5.7)Drude感应偶极子

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

人工智能|推荐系统——工业界的推荐系统之召回

基于物品的协同过滤 ⽤索引,离线计算量⼤,线上计算量⼩ Swing额外考虑重合的⽤户是否来⾃⼀个⼩圈⼦,两个⽤户重合度⼤,则可能来⾃⼀个⼩圈⼦,权重降低。 基于用户的协同过滤 同样是离线计算索引,在线召回的流程 离散特征处理 Embedding 层参数数量=向量维度 类别数量 矩

DS高阶:图论算法经典应用

一、最小生成树&#xff08;无向图&#xff09; 在了解最小生成树算法之前&#xff0c;我们首先要先了解以下的准则&#xff1a; 连通图中的每一棵生成树&#xff0c;都是原图的一个极大无环子图&#xff0c;即&#xff1a;从其中删去任何一条边&#xff0c;生成树就不在连通&a…

mysql查询数据不对

sum(id)是算id这一列的数值总和&#xff0c;无论主键与否&#xff0c;sum都是算数值总和 count(id)或count(*)是算当前列的行数&#xff0c;id是主键才行

FIFO Generate IP核使用——AXI接口FIFO简介

AXI接口FIFO是从Native接口FIFO派生而来的。AXI内存映射接口提供了三种样式&#xff1a;AXI4、AXI3和AXI4-Lite。除了Native接口FIFO支持的应用外&#xff0c;AXI FIFO还可以用于AXI系统总线和点对点高速应用。 AXI接口FIFO不支持Builtin FIFO和 Shift Register FIFO配置。 当…