第六部分:1---进程间通信,匿名管道

news2024/11/14 12:20:07

目录

进程间通信

进程间通信的目的:

进程间通信的本质:

管道:

管道的定义:

匿名管道

单向通信的管道通路:

进程和文件之间的解耦:

单向管道的读写端回收问题:

管道通信主要实现动态数据传递:

父子进程通过管道传输数据的案例:

匿名管道的4种情况:

匿名管道的5种特性:


进程间通信

进程间通信的目的:

  • 数据传输:不同进程之间需要传递信息或共享数据。

  • 资源共享:多个进程可以共享系统资源。

  • 事件通知:进程之间可以通过通信机制向对方发送信号或消息。

  • 进程控制:一个进程可以通过通信机制对另一个进程的状态进行控制,如启动、挂起、终止等操作。进程控制有助于父进程管理子进程的执行和生命周期。

进程间通信的本质:

  • 进程间同行的本质,就是让不同的进程看到同一份资源,而这份资源不是由进程提供,而是由操作系统提供。

管道:

管道的定义:

  • 管道是一种进程间通信机制,用于在两个或多个进程之间传递数据,允许一个进程的输出作为另一个进程的输入来使用。管道的本质是内存中的一块缓冲区。

  • 它通过将数据流从一个进程的标准输出(stdout)直接传送到另一个进程的标准输入(stdin),从而实现数据的流式传递。

匿名管道

  • 主要用于在父子进程或兄弟进程之间传递数据。它是最简单、最基础的管道形式,特点是单向传输,即数据只能从一端(写端)写入,从另一端(读端)读取。

  • 如果要实现双向通信,需要分别创建两个管道。

单向通信的管道通路:
  • 创建单向管道:管道的本质是内存中的一块缓冲区,在使用 pipe() 系统调用创建单向管道时,内核会自动为管道分配两个文件描述符:一个用于读端,一个用于写端。这两个文件描述符分别对应这块缓冲区的读指针和写指针。

  • 注意,管道的读写端不是直接通过文件打开两次实现,而是通过 pipe() 生成一个匿名的内存缓冲区(管道),分别分配给读端和写端。

  • 父进程fork() 后,子进程会继承父进程的文件描述符表。这意味着子进程会复制父进程的文件描述符表项,指向同一个内核文件表项和缓冲区。因此,父进程和子进程都拥有两个文件描述符,分别指向管道的读端和写端。

  • 为了实现单向通信,父进程关闭管道的读端(只需要写入数据)。子进程关闭管道的写端(只需要读取数据)。这样父进程只能往管道里写数据,而子进程只能从管道里读数据,形成单向通信。

  • 实现通信:此时,父进程通过管道的写端将数据写入内核的管道缓冲区,子进程通过管道的读端读取数据。管道内部实现了数据同步,父进程在写满缓冲区之前可以持续写数据,而子进程读取数据时会从缓冲区中取出。

进程和文件之间的解耦:

  • 文件结构体中有一个引用计数器(reference counter),用于跟踪有多少个文件描述符指向该文件。当一个新的文件描述符指向这个文件结构体时,计数器会加一;当一个文件描述符被关闭时,计数器会减一。

  • 当一个进程关闭文件描述符(例如调用 close(fd)),文件描述符表中该文件描述符所指向的文件结构体的引用计数会减少一。但此时文件并不会立即关闭,因为内核会检查这个文件结构体的引用计数。

  • 当文件结构体的引用计数降为零时,意味着没有任何文件描述符再指向该文件。这时,内核会释放与该文件相关的资源,关闭文件,清理内核中的文件表项和相关的数据结构。

  • 这种设计减少了文件与进程之间的耦合。进程不在直接管理文件的关闭,而是交给操作系统来统一管理。

单向管道的读写端回收问题:
  • 在形成单向管道后,开始传递数据,数据传递完毕,是否需要关闭父子进程的读写端呢?

  • 如果子进程在完成任务后立即退出,那么不需要显式关闭管道的读端。因为当子进程终止时,操作系统会自动回收它所持有的所有资源,包括打开的文件描述符。

  • 对于父进程,在完成数据写入后,如果不再使用管道,应显式调用 close() 关闭写端。虽然父进程退出后系统会回收资源,但在父进程继续运行的情况下,未关闭的文件描述符可能会造成资源浪费或影响其他操作。

管道通信主要实现动态数据传递:
  • 当父进程通过 fork() 创建子进程时,子进程会继承父进程的某些资源,包括文件描述符、环境变量和内存中的数据(在写时拷贝机制下),从而实现父子间的静态数据传递。这种传递的特点是:父进程的数据在创建子进程时就已经存在,子进程在初始时拥有这些数据的副本。然而这些数据是静态的,一旦子进程启动后,父子进程各自拥有自己的独立副本,互相的修改不会影响对方。

  • 如果需要在父子进程之间实现动态数据传递,即:在运行过程中父子进程能够实时通信和交换数据,静态传递方式是不够的。这种情况下,就需要使用管道(pipe)或其他进程间通信(IPC)机制来实现动态数据传递。

父子进程通过管道传输数据的案例:
#include <iostream>
#include <unistd.h>
#include <cassert>
#include <cerrno>
#include <sys/types.h>
#include <sys/wait.h>
#include <cstring>
#define MAX 1024
using namespace std;
​
int main()
{
    int pipearr[2]={0}; //创建管道
    int n = pipe(pipearr); //pipearr是一个输出型参数
    assert(n == 0); //断言是否创建成功
​
    pid_t id = fork();//创建子进程
    if (id < 0)
    {
        perror("pid");
        return 1;
    }
​
    if(id==0)
    {
        //child
        close(pipearr[0]); //子进程关闭读端
        int cnt=10;
        while(cnt) //子进程向管道写入
        {
            char mess[MAX];
            snprintf(mess,sizeof(mess),"pid:%d,cnt:%d",getpid(),cnt);
            cnt--;
            write(pipearr[1],mess,strlen(mess));
            sleep(1);
        }
        exit(0);
    }
    //parent
    close(pipearr[1]); //父进程关闭写端
    char buff[MAX];
    while(true) //父进程持续读取管道数据
    {
        ssize_t n=read(pipearr[0],buff,sizeof(buff)-1);
        if(n>0)
        {
            buff[n]='\0';
            cout<<buff<<endl;
        }
    }
​
    pid_t ret=waitpid(id,nullptr,0); //父进程等待子进程
    if(ret==id)
    {
        cout<<"wait success"<<endl;
    }
​
    return 0;
};
匿名管道的4种情况:
  • 正常情况下,管道没有数据了,读端会一直等待,直到写端写入数据到管道。

  • 正常情况下,管道被写满,写端会停止写入,直到读端读取数据后管道出现可用空间。

  • 写端关闭,读端read读取,会持续接收到返回值0,表示读到文件的结尾。

  • 读端关闭,写端进程会直接被操作系统发送13号信号杀死,可以通过父进程接受子进程的退出码验证。

匿名管道的5种特性:
  • 匿名管道,允许具有血缘关系的进程通信,常用于父子进程。

  • 匿名管道,会提供读写端的同步机制,

  • 匿名管道,面向字节流读取,他会按照你指定的大小尽可能从缓冲区读取数据,如果读写速率不匹配,每次写入很少的数据,在很多次写入后才读取一次,那么一次读取可能读取到多次写入的数据。

  • 管道是有上限的,无法一直写入。

  • 管道的生命周期跟随进程,进程结束,管道释放。

  • 管道是单向通信的,是半双工通信的一种特殊情况。

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

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

相关文章

Python VS Golng 谁更胜一筹?

今天我们聊聊Python和Golang这俩到底谁更胜一筹。 这个话题我已经在各种技术论坛上看到无数次了&#xff0c;每次都能引起一波热烈的讨论。作为一个多年写代码的老程序员&#xff0c;今天就站在我的角度&#xff0c;和大家掰扯掰扯这两个语言各自的优缺点。 1. 性能与并发模型…

283. 移动零(快慢指针)

算法分析&#xff1a; 如果数组没有0&#xff0c;快慢指针同步移动&#xff0c;元素会被自己复制&#xff1b;如果有0&#xff0c;快指针找到非零元素&#xff0c;将其复制到慢指针位置最终将剩余位置填充为0。 代码&#xff1a; class Solution {public void moveZeroes(i…

Android Studio 2024 安装、项目创建、加速、优化

文章目录 Android Studio安装Android Studio项目创建Android Studio加速修改GRADLE_USER_HOME位置减少C盘占用空间GRADLE加速 修改模拟器位置减少C盘占用空间参考资料 Android Studio安装 下载android studio download android-studio-2024.1.2.12-windows.exe 或者 android-…

11 - TCPClient实验

在上一个章节的UDP通信测试中&#xff0c;尽管通信的实现过程相对简洁&#xff0c;但出现了通信数据丢包的问题。因此&#xff0c;本章节将基于之前建立的WIFI网络连接&#xff0c;构建一个基础的TCPClient连接机制。我们利用网络调试助手工具来发送数据&#xff0c;测试网络通…

[PICO VR眼镜]眼动追踪串流Unity开发与使用方法,眼动追踪打包报错问题解决(Eye Tracking/手势跟踪)

前言 最近在做一个工作需要用到PICO4 Enterprise VR头盔里的眼动追踪功能&#xff0c;但是遇到了如下问题&#xff1a; 在Unity里面没法串流调试眼动追踪功能&#xff0c;根本获取不到Device&#xff0c;只能将整个场景build成APK&#xff0c;安装到头盔里&#xff0c;才能在…

【技术解析】消息中间件MQ:从原理到RabbitMQ实战(深入浅出)

文章目录 【技术解析】消息中间件MQ&#xff1a;从原理到RabbitMQ实战(深入浅出)1.简介1.1 什么是消息中间件1.2 传统的http请求存在那些缺点1.3 Mq应用场景有那些1.4 为什么需要使用mq1.5 Mq与多线程之间区别1.6 Mq消息中间件名词1.7主流mq区别对比1.8 Mq设计基础知识 2.Rabbi…

C++ | Leetcode C++题解之第415题字符串相加

题目&#xff1a; 题解&#xff1a; class Solution { public:string addStrings(string num1, string num2) {int i num1.length() - 1, j num2.length() - 1, add 0;string ans "";while (i > 0 || j > 0 || add ! 0) {int x i > 0 ? num1[i] - 0 …

大数据Flink(一百一十八):Flink SQL水印操作(Watermark)

文章目录 Flink SQL水印操作&#xff08;Watermark&#xff09; 一、为什么要有WaterMark 二、​​​​​​​​​​​​​​Watermark解决的问题 三、​​​​​​​​​​​​​​代码演示 Flink SQL水印操作&#xff08;Watermark&#xff09; 一、​​​​​​​为什么…

【数据结构】数据结构系列学习笔记——导航篇

一&#xff1a;概述 数据结构是计算机科学中的核心概念之一&#xff0c;是优化算法性能和资源利用率的关键。在软件开发和数据处理中&#xff0c;选择合适的数据结构对于算法的效率至关重要。数据结构的选择通常基于数据的使用模式&#xff0c;包括数据元素之间的关系、数据的存…

日志框架的使用

一、日志概述 日志&#xff1a;用来记录程序运行过程中的信息&#xff0c;并可以进行永久存储。 开发过程中可能会出现以下需求&#xff1a; 希望系统能记住某些数据是被谁操作的&#xff0c;比如被谁删除了&#xff1f;想分析用户浏览系统的具体情况&#xff0c;以便挖掘用…

【深度学习】深度学习模型的加密及解密方案及源码

本文摘要 本文主要根据自己遇到的情况,例如:对于yolo或paddle训练的模型文件,对外使用,不想要别人拿到我的模型文件随意乱用,此时就涉及到对模型文件进行加密与解密 深度学习模型的加密保护非常重要,尤其在商业应用场景下。常见的模型加密方法包括模型文件加密、加密硬件…

图像分割基本知识

计算机视觉和图像处理 Tensorflow入门深度神经网络图像分类目标检测图像分割 图像分割 一、目标分割1.1 图像分割的定义1.2 任务类型1.2.1 任务描述1.2.2 任务类型 二、语义分割2.1 FCN网络2.1.1网络结构 2.2 Unet网络 三、UNet案例3.1 数据集获取3.1.1 设置相关信息3.1.2 图像…

nature communications |多层次蛋白质组分析揭示弥漫型和肠型胃癌之间的分子多样性

文章信息 发表期刊&#xff1a;nature communications 发表日期&#xff1a;2023年2月14日 影响因子&#xff1a;14.7 研究背景 胃癌是世界上主要的癌症类型之一。弥漫型胃癌(DGC)和肠型胃癌(IGC)是胃癌(GC)的主要组织学类型&#xff0c;DGC呈分散的细胞组织&#xff0c;黏…

比特币10年价格数据(2014-2024)分析(进阶2_时间序列分析)

数据入口&#xff1a;【每周挑战】比特币10年价格数据可视化和量化分析 - Heywhale.com 本数据集包含 2014 - 2024 的比特币美元价格数据&#xff0c;具体包含比特币每日的开盘价、最高价、最低价、收盘价以及成交量等关键信息。数据说明如下&#xff1a; 字段说明Date日期&a…

iPhone 16系列:摄影艺术的全新演绎,探索影像新境界

在科技的浪潮中&#xff0c;智能手机摄影功能的进化从未停歇。 苹果公司即将推出的iPhone 16系列&#xff0c;以其卓越的相机升级和创新特性&#xff0c;再次站在了手机摄影的前沿。 从硬件到软件&#xff0c;从拍照体验到图像处理&#xff0c;iPhone 16系列都展现了其在移动…

camtasia2024绿色免费安装包win+mac下载含2024最新激活密钥

Hey, hey, hey&#xff01;亲爱的各位小伙伴&#xff0c;今天我要给大家带来的是Camtasia2024中文版本&#xff0c;这款软件简直是视频制作爱好者的福音啊&#xff01; camtasia2024绿色免费安装包winmac下载&#xff0c;点击链接即可保存。 先说说这个版本新加的功能吧&#…

Mapsui:一个 .NET 开源的地图组件库

前言 今天大姚给大家分享一个.NET开源&#xff08;MIT License&#xff09;、免费、同时支持多平台框架&#xff08;MAUI、WPF、Avalonia、Uno、Blazor、WinUI、Eto、.NET Android 和 .NET iOS&#xff09;地图组件库&#xff1a;Mapsui。 项目源代码 支持的UI框架的NuGet包 创…

华为OD机试 - 查字典(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

【研发日记】嵌入式处理器技能解锁(六)——ARM的Cortex-M4内核

文章目录 前言 背景介绍 指令集架构 ARM起源 ARM分类 Cortex-M4 内核框架 指令流水线 实践应用 总结 参考资料 前言 见《【研发日记】嵌入式处理器技能解锁(一)——多任务异步执行调度的三种方法》 见《【研发日记】嵌入式处理器技能解锁(二)——TI C2000 DSP的SCI(…

管理依赖版本-maven工程parent项目巧配置

本文目标&#xff1a;开发人员&#xff0c;在了解pom文件properties、dependencyManagement标签用法的条件下&#xff0c;进行依赖包版本统一维护&#xff0c;达到统一维护项目依赖jar包版本的程度。 文章目录 1 场景2 要点3 总结/练习 1 场景 maven工程多模块项目&#xff0c;…