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

文章目录

  • 序言
  • 目的
  • 进程间通信的理解
  • 进程间通信的发展历史
  • 管道创建
  • 验证管道的大小
  • 管道的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 1024

using 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);//减一的目的是万一缓冲区读满了,可以留出空位置来给\0
        if(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.管道是单向通信的,半双工通信的一种特殊情况
半双工:

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

全双工:

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

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

像这样的怎么实现呢?

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

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

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

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

相关文章

Java如何获取当前日期和时间?

Java如何获取当前日期和时间&#xff1f; 本文将为您介绍 Java 中关于日期和时间获取的方法&#xff0c;以及介绍 Java 8 中获取日期和时间的全新API。 1、 System.currentTimeMillis() 获取标准时间可以使用 System.currentTimeMillis() 方法来获取&#xff0c;此方法优势是…

Flutter笔记:Widgets Easier组件库(12)使用消息吐丝(Notify Toasts)

Flutter笔记 Widgets Easier组件库&#xff08;12&#xff09;使用消息吐丝&#xff08;Notify Toasts&#xff09; - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 29114848416…

Linux(openEuler、CentOS8)基于chrony企业内网NTP服务器搭建实验

一、知识点 chrony 是由 守护进程 chronyd 以及 命令行工具 chronyc 组成的 chronyd 在后台静默运行并通过 123 端口与时间服务器定时同步时间&#xff0c;默认的配置文件是 /etc/chrony.conf chronyc 通过 323 端口与 chronyd 交互&#xff0c;可监控 chronyd 的性能并在运…

单例、工厂、策略、装饰器设计模式

1. 单例模式&#xff08;Singleton Pattern&#xff09;&#xff1a; 单例模式是一种常用的设计模式&#xff0c;用于确保一个类只有一个实例&#xff0c;并提供一个全局访问点。这种模式的特点是类自己负责保存其唯一的实例&#xff0c;并控制其实例化过程。单例模式广泛应用…

微服务----nacos配置及简单使用

目录 什么是nacos 项目在nacos上进行注册 注入nacos依赖 配置application.yml文件 nacos写入配置文件 首先&#xff0c;还是需要导入依赖 然后在nacos中编写配置文件 prod是我自定义的一个命名空间&#xff0c;在这里面进行配置文件编写~ 启动类上加上注解 编写Patt…

构建智能化监控追踪系统:架构设计与实践

随着信息技术的不断发展&#xff0c;监控追踪系统在各个领域的应用越来越广泛。本文将探讨监控追踪系统的架构设计&#xff0c;介绍其关键特点和最佳实践&#xff0c;助力各行业实现智能化监控与管理。 1. **需求分析与功能设计&#xff1a;** 在设计监控追踪系统之前&#xf…

Microsoft 365 for Mac(Office 365)v16.84正式激活版

office 365 for mac包括Word、Excel、PowerPoint、Outlook、OneNote、OneDrive和Teams的更新。Office提供了跨应用程序的功能&#xff0c;帮助用户在更短的时间内创建令人惊叹的内容&#xff0c;您可以在这里创作、沟通、协作并完成重要工作。 Microsoft 365 for Mac(Office 36…

HTML/CSS1

1.前置说明 请点这里 2.img元素 格式&#xff1a; <img src"图片地址" alt"占位文字" width"图片宽度" height"图片高度">其中alt是当图片加载失败时显示的文字 而且不同内核的浏览器显示出来的占位文字的效果也是不尽相同的…

K8S哲学 - 资源调度 HPA (horizontal pod autoScaler-sync-period)

kubectl exec&#xff1a; kubectl exec -it pod-name -c container-name -- /bin/sh kubectl run 通过一个 deployment来 演示 apiVersion: apps/v1 kind: Deployment metadata:name: deploylabels: app: deploy spec: replicas: 1selector: matchLabels:app: deploy-podt…

加州大学欧文分校英语中级语法专项课程04:Intermediate Grammar Project学习笔记(完结)

Intermediate Grammar Project Course Certificate Specialization Certificate Specialization Intro Course Intro 本文是学习 Coursera: Intermediate Grammar Project 这门课的学习笔记。 文章目录 Intermediate Grammar ProjectWeek 01: IntroductionCapstone Introducti…

解密中国首个“音乐版Sora” | 最新快讯

编辑部发自 AIGC 峰会 量子位公众号 QbitAI 文生图、文生音频、文生视频、AI 搜索引擎……大模型在多模态的进程可谓是愈演愈烈。 而聚焦在国内&#xff0c;有这么一家公司在 AIGC 大热潮的前后&#xff0c;单是“首个”就占了四席&#xff1a; 发布中国首个开源文本大模型国内…

基于OpenCv的图像全景拼接

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计6757字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

【数据结构(十)】Map和Set

❣博主主页: 33的博客❣ ▶️文章专栏分类:数据结构◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你学更多数据结构知识 目录 1.前言2.搜索树2.1 概念2.2实现二叉搜索树 2.4性能分析3.搜索3.Map3.1Map说明3.2 M…

vue3使用el-autocomplete请求远程数据

服务器端 RestController RequestMapping("/teacher") public class TeacherController {Resourceprivate TeacherService teacherService;GetMapping({"/v1/getTop10TeacherByName/","/v1/getTop10TeacherByName/{name}"})public ResultBean&l…

论文笔记:(Security 22) 关于“二进制函数相似性检测”的调研

个人博客链接 注&#xff1a;部分内容参考自GPT生成的内容 [Security 22] 关于”二进制函数相似性检测“的调研&#xff08;个人阅读笔记&#xff09; 论文&#xff1a;《How Machine Learning Is Solving the Binary Function Similarity Problem》&#xff08;Usenix Securi…

C++多态特性详解

目录 概念&#xff1a; 定义及实现&#xff1a; 虚函数重写的两个例外&#xff1a; 1.协变&#xff1a; 2.析构函数的重写&#xff1a; final关键字&#xff1a; override关键字&#xff1a; 多态是如何实现的&#xff08;底层&#xff09;&#xff1a; 面试题&#xff1…

图像识别及分类

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

【网络编程下】五种网络IO模型

目录 前言 一.I/O基本概念 1.同步和异步 2.阻塞和非阻塞 二.五种网络I/O模型 1.阻塞I/O模型 2.非阻塞式I/O模型 ​编辑 3.多路复用 4.信号驱动式I/O模型 5. 异步I/O模型 三.五种I/O模型比较​编辑 六.I/O代码示例 1. 阻塞IO 2.非阻塞I/O 3.多路复用 (1)select …

Rust web简单实战

一、使用async搭建简单的web服务 1、修改cargo.toml文件添加依赖 [dependencies] futures "0.3" tokio { version "1", features ["full"] } [dependencies.async-std] version "1.6" features ["attributes"]2、搭…

【Leetcode每日一题】 综合练习 - 全排列 II(难度⭐⭐)(71)

1. 题目解析 题目链接&#xff1a;47. 全排列 II 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 算法思路梳理 为了生成给定数组nums的全排列&#xff0c;同时避免由于重复元素导致的重复排列&#xff0c;我们可以遵…