Linux——进程通信(一) 匿名管道

目录

前言

一、进程间通信

二、匿名管道的概念

三、匿名管道的代码实现

四、管道的四种情况

1.管道无数据,读端需等待

2.管道被写满,写端需等待

3.写端关闭,读端一直读取

4.读端关闭,写端一直写入

五、管道的特性


前言

之前我们学习的进程,都是进程自己干自己的事情,最多就父进程等待一下子进程,两个进程自己完成自己的任务,并没有太多关系,虽说进程具有独立性,但进程并不孤僻,进程之间交流是可以完成的,今天我们就来学习进程通过匿名管道进行通信,匿名管道并不难,不要被它名字唬住了。

一、进程间通信

进程间通信的目的如下 

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

要实现这些目的的前提,就是进程间可以通信起来。但是我们知道进程具有独立性,如果数据传输通过数据拷贝的方式进行,也就是将A进程的数据直接拷贝给B进程,这样就破坏了进程的独立性。这时就需要一个AB进程都能去到的地方,往这个共享区进行读写,这样就能保证进程独立性的同时,还实现了通信的功能,操作系统就很适合当这个中间人

进程间通信的本质:让不同的进程看到同一份资源

进程间通信分类分为管道、System V进程间通信、POSIX进程间通信。今天我们着重学习管道中的匿名管道

二、匿名管道的概念

        首先,我们知道一个进程有他的task_struct,这里面有一个指向文件结构体的指针,该文件结构体里面存在文件标识符数组,数组0号下标指向键盘(stdin),1指向显示器(stdout),2指向显示器(stderr)。

        现在,我新打开一个文件,那么该文件的文件标识符就为3,此时我fork创建子进程,子进程要继承父亲的task_struct、虚拟地址空间、页表等等,都继承了task_struct了,那么files_struct也要继承一份(因为如果共用files_struct,那么子进程想打开新的文件,肯定会往文件标识符数组里面写内容,那么父进程也会看见,这岂不是破坏了进程的独立性)。

        既然files_struct也继承了,里面指向的新文件也肯定继承了,文件有文件缓冲区,如果我父进程往该文件进行写入,子进程对文件进行读取,这样是不是就完成了进程间的通信。(注意:虽然文件缓冲区一般情况是要刷新到磁盘中的,但是这里文件只充当了管道的作用,刷新到磁盘再读取磁盘的效率非常低,因此这里并不会涉及到磁盘,只是内存级别的数据拷贝)

但是这里还存在一点小问题,就是父进程如果只是只读方式打开文件,那么子进程也是只读的方式打开文件,并不能写入,因此需要父进程同时对一个文件进行打开读取和打开写入操作,子进程继承下来后,既可以读取又可以写入,那么到时候,我想让子进程写,父进程读,就只需关闭子进程读,父进程写就可以了,反之亦然。

我们对同一文件进行读和写,在内核数据结构中实际上会生成两个struct file,只不过这两个struct file,都指向的是同一个inode,同一个缓冲区。进程关闭文件时,将文教标识符数组清空,file里面的引用计数 -- ,进程就不管文件了,但操作系统还得判断当前文件引用计数是否为0,为0证明没有进程还在使用该文件,就可以关闭,不为0就不会真正的关闭。

这就是管道名字的由来,只支持一边读,另一边写,是半双工的一种特殊方式。 同时这个管道我们并不关心它的名字,因此叫做匿名管道。

管道是Unix中最古老的进程间通信的形式。

在linux命令中,|  就是管道,可以将输出的信息读取给后面的命令处理。

三、匿名管道的代码实现

由于管道接口是不需要将数据刷新到外设,因此接口需要特殊设计。

#include 功能:创建一无名管道

原型         int pipe(int fd[2]);

参数         fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端

返回值:成功返回0,失败返回错误代码

我们直接上代码,利用pipe创建管道,子进程去写数据,父进程来读数据 

#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cstring>
#include <cassert>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;

#define MAX 1024
int main()
{
    // 建立管道
    int pipefd[2] = {0};
    int n = pipe(pipefd);
    assert(n==0);   //release模式不会执行

    pid_t id = fork();
    if (id < 0)
    {
        perror("fork");
        return 1;
    }
    // 子写 父读
    if (id == 0)
    {
        // child
        close(pipefd[0]);
        char message[MAX];
        int cnt = 10;
        while(cnt)
        {
            snprintf(message, MAX, "hello father,I am child,pid: %d,cnt: %d ", getpid(),cnt);
            write(pipefd[1],message,strlen(message));
            cnt--;
            sleep(1);
        }
        exit(0);
    }

    // 父进程
    close(pipefd[1]);
    char buff[MAX];
    while (true)
    {
        ssize_t n = read(pipefd[0], buff, MAX - 1);
        if (n > 0)
        {
            buff[n] = '\0';
            cout << getpid()<<", child say:" << buff << "to me!" << endl;
        }
    }
    pid_t rid = waitpid(id, NULL, 0);
    if (rid = id)
    {
        cout << "wait success" << endl;
    }
    return 0;
}

成功进行数据通信

四、管道的四种情况

1.管道无数据,读端需等待

如果管道中没有数据了,读端需要等待,直到写段写入数据。

我们让子进程休眠100秒

 发现父子进程都在休眠,印证了管道中没有数据,读端并不会一直运行。

2.管道被写满,写端需等待

管道被写满了,写端需要等待,等读端读走数据才可以继续写。

我们让写端死循环写入,读端进行休眠。

发现写端写到一定数据后不动了。 他需要等待读端读取数据再写入。

3.写端关闭,读端一直读取

我们关闭写端,读端一直读取,读端会读到read返回值为0,表示文件结尾。

以下是写端休眠100秒,一直不写,读端读数据,看n返回多少,都会打印。

 程序没有结果,这也印证了上面的情况,写端不写入,读端需等待,read不会返回值。

后面让读端关闭,查看写端打印结果 

写端关闭了,因此可以返回值,n == 0,表示读到文件末尾。

4.读端关闭,写端一直写入

读端关闭,写端一直写入,操作系统会发送 SIGPIPE 直接杀掉写端进程。

退出码为13。

发送了13号  SIIGPIPE

五、管道的特性

  1. 匿名管道,允许有血缘关系的进程通信
  2. 匿名管道,默认读写段要提供同步机制
  3. 面向字节流
  4. 管道的声明周期随进程(进程死亡,文件自然close,管道也不存在了)
  5. 管道式单向通信的,半双工通信的一种特殊情况。

 

 

 

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

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

相关文章

不锈钢多功能电工剥线钳分线绕线剪线剥线钳剥线压线扒皮钳子

品牌&#xff1a;银隆 型号&#xff1a;089B绿色 材质&#xff1a;镍铬钢&#xff08;不锈钢&#xff09; 颜色分类&#xff1a;089B灰色,089B红色,089B绿色,089B黑色,089B橙色 功能齐集一身&#xff0c;一钳多用&#xff0c;多功能剥线钳。剥线&#xff0c;剪线&#xff…

Java-CAS 原理与 JUC 原子类

由于 JVM 的 synchronized 重量级锁涉及到操作系统&#xff08;如 Linux&#xff09; 内核态下的互斥锁&#xff08;Mutex&#xff09;的使用&#xff0c; 其线程阻塞和唤醒都涉及到进程在用户态和到内核态频繁切换&#xff0c; 导致重量级锁开销大、性能低。 而 JVM 的 synchr…

免费阅读篇 | 芒果YOLOv8改进114:上采样Dysample:顶会ICCV2023,轻量级图像增采样器,通过学习采样来学习上采样,计算资源需求小

&#x1f4a1;&#x1f680;&#x1f680;&#x1f680;本博客 改进源代码改进 适用于 YOLOv8 按步骤操作运行改进后的代码即可 该专栏完整目录链接&#xff1a; 芒果YOLOv8深度改进教程 &#x1f680;&#x1f680;&#x1f680; DySample是一个超轻量级和有效的动态上采样器…

DDos攻击如何被高防服务器有效防范?

德迅云安全-领先云安全服务与解决方案提供商 什么是DDos攻击&#xff1f; DDos攻击是一种网络攻击手段&#xff0c;旨在通过使目标系统的服务不可用或中断&#xff0c;导致无法正常使用网络服务。DDos攻击可以采取多种方式实施&#xff0c;包括洪水攻击、压力测试、UDP Flood…

HTML静态网页成品作业(HTML+CSS)——游戏战地介绍设计制作(4个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有4个页面。 二、作品演示 三、代…

关于PXIE3U18槽背板原理拓扑关系

如今IT行业日新月异&#xff0c;飞速发展&#xff0c;随之带来的是数据吞吐量的急剧升高。大数据&#xff0c;大存储将成为未来数据通信的主流&#xff0c;建立快速、大容量的数据传输通道将成为电子系统的关键。随着集成技术和互连技术的发展&#xff0c;新的串口技术&#xf…

【QT+QGIS跨平台编译】之七十七:【QGIS_Gui跨平台编译】—【错误处理:字符串错误】

文章目录 一、字符串错误二、处理方法三、涉及到的文件一、字符串错误 常量中有换行符错误:(也有const char * 到 LPCWSTR 转换的错误) 二、处理方法 需要把对应的文档用记事本打开,另存为 “带有BOM的UTF-8” 三、涉及到的文件 src\gui\qgsadvanceddigitizingdockwidge…

ClickHouse中的设置的分类

ClickHouse中的各种设置 ClickHouse中的设置有几百个&#xff0c;下面对这些设置做了一个简单的分类。

【Godot 4.2】常见几何图形、网格、刻度线点求取函数及原理总结

概述 本篇为ShapePoints静态函数库的补充和辅助文档。ShapePoints函数库是一个用于生成常见几何图形顶点数据&#xff08;PackedVector2Array&#xff09;的静态函数库。生成的数据可用于_draw和Line2D、Polygon2D等进行绘制和显示。因为不断地持续扩展&#xff0c;ShapePoint…

Orbit 使用指南 03 | 与刚体交互 | Isaac Sim | Omniverse

如是我闻&#xff1a; “在之前的指南中&#xff0c;我们讨论了独立脚本&#xff08; standalone script&#xff09;的基本工作原理以及如何在模拟器中生成不同的对象&#xff08;prims&#xff09;。在指南03中&#xff0c;我们将展示如何创建并与刚体进行交互。为此&#xf…

机器学习周记(第三十周:文献阅读-SageFormer)2024.3.11~2024.3.17

目录 摘要 ABSTRACT 1 论文信息 1.1 论文标题 1.2 论文摘要 1.3 论文背景 2 论文模型 2.1 问题描述 2.2 模型信息 2.2.1 Series-aware Global Tokens&#xff08;序列感知全局标记&#xff09; 2.2.2 Graph Structure Learning&#xff08;图结构学习&#xff09; …

大数据面试题之SQL题

大数据面试题之SQL题 1.有一个录取学生人数表&#xff0c;记录的是每年录取学生人数和入学学生的学制 以下是表结构&#xff1a; CREATE TABLE admit ( id int(11) NOT NULL AUTO_INCREMENT, year int(255) DEFAULT NULL COMMENT ‘入学年度’, num int(255) DEFAULT NULL COMM…

交流互动系统|基于springboot框架+ Mysql+Java+Tomcat的交流互动系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…

【医学图像处理】ECAT和HRRT格式转nii格式【超简单】

之前从ADNI上下载PET数据的时候发现有许多数据的格式不是DICOM的而是ECAT或者是HRRT格式&#xff0c;这对原本就少的PET数据是血上加霜啊。 当然只使用DICOM格式的数据也会得到不少的数据&#xff0c;我一开始也是只使用DICOM格式的样本&#xff0c;后来为了得到更多的数据&a…

2024年值得创作者关注的十大AI动画创新平台

别提找大型工作室制作动画了。如今,AI平台让我们就可以轻松制作动画。从简单的文本生动画功能到复杂的角色动作,这些平台为各种类型的创作者提供了不同的功能。 AI已经有了长足的发展,现在它可以理解复杂的人类动作和艺术意图,将简单的输入转化成丰富而详细的动画。 下面…

RoketMQ主从搭建

vim /etc/hosts# IP与域名映射&#xff0c;端口看自己的#nameserver 192.168.126.132 rocketmq-nameserver1 192.168.126.133 rocketmq-nameserver2# 注意主从节点不在同一个主机上 #broker 192.168.126.132 rocketmq-master1 192.168.126.133 rocketmq-master2#broker 192.168…

HarmonyOS(鸿蒙)不再适合JS语言开发

ArkTS是鸿蒙生态的应用开发语言。它在保持TypeScript&#xff08;简称TS&#xff09;基本语法风格的基础上&#xff0c;对TS的动态类型特性施加更严格的约束&#xff0c;引入静态类型。同时&#xff0c;提供了声明式UI、状态管理等相应的能力&#xff0c;让开发者可以以更简洁、…

用Python 3 开发的摄像头拍照程序

在当今数字化的世界中&#xff0c;使用摄像头进行拍照已成为日常生活的重要组成部分。无论是用于个人用途还是专业用途&#xff0c;能够使用电脑摄像头轻松拍照都是一项有用的技能。本文将指导您使用 Python 3 编写一个简单的程序&#xff0c;让您能够使用电脑摄像头拍照并将其…

如果网络不好 如何下载huggingface上的模型

很多朋友网络不太好&#xff0c;有时候上不了huggingface这样的国外网站&#xff1b; 或者网络流量不太够&#xff0c;想要下载一些stable diffusion模型&#xff0c;或者其他人工智能的大模型的时候&#xff0c;看到动辄几个G的模型文件&#xff0c;不太舍得下载&#xff1b;…

9. 综合案例-ATM系统 (1~7节知识综合练习)

ATM系统_综合大练习 今天的任务是对之前所有的学习的知识, 进行一个综合性的大练习. 老师说的好, 键盘敲烂 这个项目我写了大量的注释给大家参考, 如果有同学是跟着我的系列学习的, 一定动手练一练. 下面的代码只要按着敲是可以直接运行起来的, 我也把完整代码上传到了CSDN上…