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

目录

进程间通信

进程间通信的目的:

进程间通信的本质:

管道:

管道的定义:

匿名管道

单向通信的管道通路:

进程和文件之间的解耦:

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

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

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

匿名管道的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.mfbz.cn/a/879396.html

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

相关文章

Java多线程-(线程的创建,线程安全,线程状态)

第一章.创建线程的方式 1.第一种方式_extends Thread 1.定义一个自定义线程类继承Thread 2.重写run方法(run方法是用于设置线程任务的) 3.创建自定义线程类对象 4.调用Thread类中的start方法(start方法:开启线程,jvm自动执行run方法) public class MyThread extends Thread{…

MacOS安装MAT教程

MAT下载地址MAT下载地址MAT下载地址MAT下载地址 如果不知道你的芯片类型, 可以执行如下命令 uname -m

VMware中安装win7和kail等虚拟机

主要内容 第一部分 安装win 7第二部分 安装kali第三部分 安装UbuntuUbuntu22.04上安装PwntoolsUbuntu上安装vim 第四部分 安装win 10office Word全套安装教程 第一部分 安装win 7 1.打开安装好的虚拟机 参考链接&#xff1a;虚拟机VMware安装windows7 64位操作系统&#x…

(娱乐)魔改浏览器-任务栏图标右上角加提示徽章

一、目标&#xff1a; windows中&#xff0c;打开chromium&#xff0c;任务栏中会出现一个chromium的图标。我们的目标是给这个图标的右上角&#xff0c;加上"有1条新消息"的小提示图标&#xff0c;也叫徽章(badge)注意&#xff1a;本章节纯属娱乐&#xff0c;有需要…

阿里巴巴搜索API返回值:电商市场竞争的新武器含

阿里巴巴搜索API返回值在电商市场竞争中扮演着至关重要的角色&#xff0c;它为企业提供了深入了解市场、分析竞争对手的宝贵资源。以下是对阿里巴巴搜索API返回值及其在电商市场竞争中应用的详细解析&#xff0c;并附上示例代码。 一、阿里巴巴搜索API返回值概述 阿里巴巴搜索…

【案例71】配置https之后 IE打不开登陆页面 Uclient没有问题

问题现象 配置https之后 IE打不开登陆页面 Uclient没有问题。 jvm控制台 显示如下 basic: 已调整小应用程序大小且已将其添加到父容器中 basic: PERF: AppletExecutionRunnable - applet.init() BEGIN ; jvmLaunch dt 170755 us, pluginInit dt 722531 us, TotalTime: 89328…

Spring4-IoC2-基于注解管理bean

目录 开启组件扫描 使用注解定义bean Autowired注入 场景一&#xff1a;属性注入 场景二&#xff1a;set注入 场景三&#xff1a;构造方法注入 场景四&#xff1a;形参注入 场景五&#xff1a;只有一个构造函数&#xff0c;无注解 场景六&#xff1a;Autowired和Quali…

4款AI生成PPT工具推荐,提升工作效率

在如今的工作环境中&#xff0c;PPT制作是许多技术人员不可避免的任务&#xff0c;尤其是在汇报、展示技术方案、以及项目进展时。随着AI技术的快速发展&#xff0c;使用AI生成PPT成为了提高效率的一种新趋势。本文将介绍几款适合程序员、技术人员的AI生成PPT工具&#xff0c;帮…

C++伟大发明--模版

C起初是不受外界关注的&#xff0c;别人觉得他和C语言没有本质上的区别&#xff0c;只是方便些&#xff0c;直到祖师爷发明了模版&#xff0c;开始和C语言有了根本的区别。 我们通过一个小小的例子来搞清楚什么是模版&#xff0c;模版的作用到底有多大&#xff0c;平时我们想要…

【HarmonyOS】鸿蒙头像上传-(编辑个人信息页- 头像上传)+实时数据更新

#效果图 #思路 ##步骤&#xff1a; ###一、利用picker api选择1张图片 实例化选择器参数(使用new PhotoSelectOptions())实例化图片选择器 (使用newPhotoViewPicker() )调用图片选择器的select方法传入选择器参数完成图片选取获得结果 利用picker api选择1张图片 async sele…

【Java】线程的同步——synchronized、ReentrantLock

对同一个线程&#xff0c;能否在获取到锁以后继续获取同一个锁? 答案是肯定可以获取同一个锁。因为JVM 允许同一个线程重复获取同一个锁&#xff0c;这种能被同一个线程反复获取的锁&#xff0c;就叫做可重入锁。 一、synchronized同步锁 在 Java中synchronized 同步锁…

Windows11 WSL2的ubuntu 22.04中拉取镜像报错

问题描述 在windows11 WSL2的ubuntu 22.04中拉取镜像报错。错误为&#xff1a; Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting header…

Java音视频文件解析工具

文章目录 一 jave-all-deps二 具体用法2.1 添加依赖2.2 视频转音频2.3 视频格式转换2.4 获取视频时长 三 总结 小伙伴们知道&#xff0c;松哥平时录了蛮多视频课程&#xff0c;视频录完以后&#xff0c;就想整理一个视频文档出来&#xff0c;在整理视频文档的时候&#xff0c;就…

[Python学习日记-25] 哈希(HASH)是个什么东西?

[Python学习日记-25] 哈希&#xff08;HASH&#xff09;是个什么东西&#xff1f; 简介 哈希的特性 哈希的用途 基于 HASH 的数据类型 简介 哈希&#xff08;Hash&#xff09;&#xff0c;也称为散列&#xff0c;或音译为哈希&#xff0c;是把任意长度的输入&#xff08;又…

idea连接docker 自动化部署

进入Linux服务器 vim /lib/systemd/system/docker.service将 ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock 替换为 ExecStart/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock新建文件 Dockerfile配置Dockerfile文…

iOS六大设计原则设计模式

六大设计原则&#xff1a; 一、单一职责原则 一个类或者模块只负责完成一个职责或者功能。 类似于&#xff1a;UIView 和 CALayer 二、开放封闭原则 对扩展开放&#xff0c;对修改封闭。 我们要尽量通过扩展软件实体来解决需求变化&#xff0c;而不是通过修改已有的代码来…

『功能项目』窗口可拖拽脚本【59】

本章项目成果展示 我们打开上一篇58第三职业弓弩的平A的项目&#xff0c; 本章要做的事情是给坐骑界面挂载一个脚本让其显示出来的时候可以进行拖拽 创建脚本&#xff1a;DraggableWindow.cs using UnityEngine; using UnityEngine.EventSystems; public class DraggableWindo…

nodejs+express+vue教辅课程辅助教学系统 43x2u前后端分离项目

目录 技术栈具体实现截图系统设计思路技术可行性nodejs类核心代码部分展示可行性论证研究方法解决的思路Express框架介绍源码获取/联系我 技术栈 该系统将采用B/S结构模式&#xff0c;开发软件有很多种可以用&#xff0c;本次开发用到的软件是vscode&#xff0c;用到的数据库是…

烧结银胶成为功率模块封装新宠

烧结银胶成为功率模块封装新宠 在科技日新月异的今天&#xff0c;材料科学作为推动工业进步的重要基石&#xff0c;正不断涌现出令人瞩目的创新成果。其中&#xff0c;善仁烧结银胶作为微电子封装领域的一项重大突破&#xff0c;正以其独特的性能优势&#xff0c;逐步成为连接…

Docker torchserve 部署模型流程

1.拉取官方镜像 地址: https://hub.docker.com/r/pytorch/torchserve/tags docker pull pytorch/torchserve:0.7.1-gpu2. docker启动指令 CPU docker run --rm -it -d -p 8380:8080 -p 8381:8081 --name torch-server -v /path/model-server/extra-files:/home/model-serve…