进程间的通信(IPC)基础了解,匿名管道使用,有名管道使用

news2024/11/24 2:14:05

进程间通信基本知识

进程间通信的定义

进程间通信方式分类

匿名管道(pipe)

匿名管道介绍

  • 创建方式:使用 pipe 系统调用创建,返回一对文件描述符(读端和写端)。
  • 生命周期:匿名管道的生命周期与创建它的进程有关。当进程结束时,匿名管道会被销毁。
  • 作用域:通常用于有亲缘关系的进程(如父子进程)之间的通信。

匿名管道常见用法

  1. 创建管道pipe(pipefd),pipefd是我们自定义的一个数组,将数组传递给pipe函数是为了存储pipe创建匿名管道时提供的两个文件描述符,我们的pipefd 数组中的 pipefd[0] 是读端文件描述符,pipefd[1] 是写端文件描述符。
  2. 写入数据write(pipefd[1], data, size),将数据写入管道。
  3. 读取数据read(pipefd[0], buffer, size),从管道读取数据。
  4. 关闭管道:使用 close(pipefd[0])close(pipefd[1]) 关闭读端和写端,释放资源。

创建匿名管道看起来似乎用到的是管道文件来进行通讯,但实际上并不是的,这里和管道文件时没有什么关联的,管道文件是真实存在于文件系统中的一种类型文件,我们可以用ls,rm这些命令对其进行操作。

匿名管道通过操作系统内核维护一个内存缓冲区一对文件描述符(分别对应于管道的读端和写端)来实现进程之间的通信。当你创建一个匿名管道时,操作系统内核会分配和管理这个内存缓冲区,以支持数据的传输。数据从写端写入缓冲区,另一个进程从读端读取数据。虽然这里的缓冲区不是文件,但是我们可以将匿名管道视作一个文件来对其进行操作,使用read,write,和两个文件描述符来对文件进行读写

匿名管道的特点

亲缘关系通常用于有亲缘关系的进程(如父子进程)之间的通信。管道的读端和写端在父进程和子进程之间共享文件描述符。

为什么使用匿名管道通信的进程必须是亲缘关系???请看下面图文解释:

  • 当一个进程通过 pipe() 系统调用创建匿名管道时,内核会返回两个文件描述符(一个用于读,一个用于写,对应匿名管道的读端和写端)。这些文件描述符是进程在内核中访问管道的唯一标识。
  • 继承机制:在UNIX和Linux系统中,当一个进程通过 fork() 创建子进程时,子进程会继承父进程的所有文件描述符。这意味着子进程可以使用与父进程相同的文件描述符来访问管道,从而实现进程间的通信。
  • 无文件系统接口:匿名管道不会在文件系统中创建实际文件,所以只能依靠文件描述符来访问。如果进程之间没有亲缘关系(如没有使用 fork()),则它们无法直接共享这些文件描述符。

 一对一通信每个匿名管道只能实现两个进程之间的单向通信。

        匿名管道的设计本质上是一种“点对点”通信方式,即两个进程之间直接传输数据。虽然可以让多个进程共享匿名管道的文件描述符,但这会导致数据读取的竞争或写入的混乱,所以并不推荐这样使用。

         单向通信匿名管道是半双工的,这意味着数据只能在一个方向流动。你需要两个匿名管道来实现双向通信,其中一个用于从进程A到进程B的数据流,另一个用于从进程B到进程A的数据流。

        匿名管道确实是半双工的,这意味着在给定时间内,数据只能在一个方向上流动。然而,半双工并不禁止你在不同的时间段内切换通信方向——你可以在一个时间段内让进程A写、进程B读,之后再让进程B写、进程A读。

        尽管切换通信方式在理论上可行,但在实际开发中,由于其复杂性和潜在的同步问题,通常不会这样操作。更直观、简单的方法是使用两个管道或选择其他更合适的IPC机制

匿名管道的使用

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>

int main(void)
{
    // 创建匿名管道
    int fd[2];//保存匿名管道的两个文件描述符
    pipe(fd);
    pid_t pid=fork();

    // 子进程
    if(pid == 0)
    {
        // 向父进程打招呼
        char *msg = "hello parent!";
        //sleep(2);
        write(fd[1], msg, strlen(msg));

        exit(0);
    }

    // 父进程
    if(pid > 0)
    {
        char buf[50];
        bzero(buf, 50);

        // 静静地等待子进程的消息
        read(fd[0], buf, 50);

        printf("来自子进程: %s\n", buf);
        exit(0);
    }
}

看到这个代码和结果你可能觉得是偶然,确实,由于父进程和子进程并发执行,前提是子进程先从匿名管道写端写入数据,父进程才能正确读到并打印子进程传输的消息。

所以这里不妨让子进程在写之前sleep(2);结果你会发现父进程仍然成功收到并且打印出了子进程传递信息,只不过是延迟了两秒,证明父进程被阻塞等待子进程传递信息过来,接下来让我们详细说一下匿名管道的读写规则

匿名管道的读写规则

操作受到阻塞的情况(2)

读写端正常,若管道如果为空,读端就要阻塞;
读写端正常,若管道如果被写满,写端被阻塞;

操作正常执行的情况(4)

读写端正常,读的时候,管道中有数据;
读写端正常,写的时候,管道中未被写满;
读端正常,无写端,读的时候,管道中有数据;
读端正常,无写端,读的时候,管道中无数据,这个read操作返回0,说明管道缓冲区数据读完了,也算read正常执行;

操作不正常的情况(2)

只要没有读端,任何试图写入管道的操作都会触发 SIGPIPE 信号,而不论管道的缓冲区是否已满。

匿名管道无用的文件描述符及时关闭

一般而言,不需要用到的文件描述符都最好及时关闭,避免不必要的副作用或浪费系统资源。例如上述程序中,子进程只用到了管道的写端,因此它的fd[0]可以也应该要关闭,相反父进程只用到了管道的读端,因此它的fd[1]可以也应该关闭。代码可以改成:

int main(void)
{
    // 创建匿名管道
    int fd[2];
    pipe(fd);

    // 子进程
    if(fork() == 0)
    {
        // 关掉不必要的读端
        close(fd[0]);

        ...
    }

    // 父进程
    else
    {
        // 关掉不必要的写端
        close(fd[1]);

        ...
    }
}

如果我们需要实现双向通信,则最好使用两个管道,然后将里面不必要的文件描述符都及时关闭。 

命名管道(fifo)

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

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

相关文章

为什么说RAG是AI 2.0时代的“杀手级”应用?

复旦AI博士&#xff0c;分享AI领域全维度知识与研究。应极客时间邀请开设《RAG快速开发实战》课程&#xff0c;感兴趣的同学可以访问关注 https://time.geekbang.com/column/intro/100804101 随着 AI 2.0 时代的来临&#xff0c;我们正站在一个技术革新和行业变革的交汇点。大语…

Vue3优化表单标签与布局,解决文字过长问题(附Demo)

目录 前言1. 增加标签宽度&#xff08;生效&#xff09;2. 工具提示 Tooltip&#xff08;勉勉强强&#xff09;3. 缩小字体&#xff08;不生效&#xff09;4. CSS 控制换行&#xff08;不推荐&#xff09; 前言 好不容易构思整个表单的布局&#xff0c;但是个别表单的文字过长…

springboot整合logback进行日志管理(上篇)

1、前言: 在日常开发中日志的打印与日志的记录是非常重要的。市面上主流的日志管理框架有log4j、logback,二者各有优缺点v,由于项目中比较常用的是logback(我们自己项目就是用的logback),进行就主要介绍一下logback在真是项目中是如何整合的。 2、springboot默认整合的logb…

NASA数据集:50 m分辨率的雪水当量(SWE)地图的集合

ASO L4 Lidar Snow Water Equivalent 50m UTM Grid V001 ASO L4 激光雷达雪水当量 50 米UTM 网格&#xff0c;第 1 版 简介 该数据集包含 50 米网格雪水当量 (SWE) 值&#xff0c;是 NASA/JPL 机载雪地观测站 (ASO) 飞机勘测活动的一部分。 这些数据来自 ASO L4 Lidar Snow …

OLED预警系统与按键菜单交互代码实操

引言 OLED顾名思义就是一个屏幕, 我们让一个屏幕在特定的时间, 显示特定的画面, 就是我们所需要的, 因为这里是涉及到环境预警,所以需要加入一个应急接管页面的选项, 所以我们要把按键直接操作画面, 变成按键操作完, 我们根据优先级判断之后, 才能确定要显示的是哪个画面. 比如…

【无标题】书生大模型实战营闯关记录----第十二关:茴香豆:企业级知识库问答工具;Web版茴香豆使用教程;茴香豆本地化标准版部署搭建教程;知识库构建问答

0 茴香豆介绍 茴香豆 是由书生浦语团队开发的一款开源、专门针对国内企业级使用场景设计并优化的知识问答工具。在基础 RAG 课程中我们了解到&#xff0c;RAG 可以有效的帮助提高 LLM 知识检索的相关性、实时性&#xff0c;同时避免 LLM 训练带来的巨大成本。在实际的生产和生活…

Yolov5 AI学习笔记

Yolov5 AI学习笔记 环境准备 需要Python的开发环境&#xff0c;安装Anaconda。 Anaconda的一些命令&#xff1a; # 创建虚拟环境 conda create -n yolo_cpu python3.9 # 查看虚拟环境 conda env list # 激活虚拟环境 conda activate <env_name>Yolov5上手 下载源码 …

上下文的弹性

“上下文的弹性”是指在自然语言处理中&#xff0c;模型对输入文本的上下文信息的理解和利用能力。它描述了模型在处理文本时能够根据上下文信息来调整其输出的程度。具有弹性上下文的模型可以更好地处理自然语言中的语义和语境&#xff0c;从而提供更准确和有用的回答。这种弹…

这才是老板喜欢的产品经理简历

速创猫今天给大家分享的是应届毕业生产品经理简历优化案例&#xff0c;希望对大家求职有帮助。速创猫总结了以下七条简历制作干货&#xff0c;希望对大家有帮助&#xff1a; 明确目标岗位&#xff1a;在简历的开头&#xff0c;明确指出你申请的职位&#xff0c;让招聘者一眼就能…

聚焦AI4SE软件工程领域,基于Multi Agent System多智能体系统开发的最新成果,实现软件开发领域的PUGC!

可能有很多小伙伴不了解AI4SE是什么&#xff0c;其实从字意上就不难看出一定是和AI相关。 AI4SE&#xff08;Artificial Intelligence for Software Engineering&#xff09;是指将人工智能技术应用于软件工程领域。 其核心目标是通过自动化和智能化技术降低软件开发的复杂性…

MySQL 官方高可用方案 InnoDB Cluster

文章目录 前言1. 方案构成2. 使用要求和限制3. 集群部署3.1 环境说明3.2 软件下载3.2 MySQL Server 安装3.3 MySQL Shell 安装3.4 检测实例是否符合资格3.5 创建集群3.6 向集群中添加节点3.7 配置 Router3.8 测试验证 4. 集群运维4.1 Router 服务管理4.2 MySQL 服务管理4.3 集群…

结束Linux特定端口上的进程,超级实用!

在使用 Linux 时&#xff0c;您可能会遇到特定端口被进程占用的情况。了解如何终止在特定端口上运行的进程可能非常有用&#xff0c;特别是对于排除故障和有效地管理系统而言。 本文中&#xff0c;我们将完成查找端口号、识别使用该端口的进程以及安全停止该进程。 详细步骤 …

【最全深度学习介绍】基本概念、类型、应用、优缺点、与机器学习区别是什么?

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发…

PostgreSQL技术内幕6:PostgreSQL索引技术

文章目录 0. 简介1.PG索引类型介绍2. PG创建索引说明及索引属性查看2.1 创建说明2.2 查看方式2.2.1 查看PG默认支持的索引及对应的Handler类型2.2.2 查看B树索引属性 3. 索引选择3.1 查看索引情况 4.PG中B-Tree索引原理4.1 页存储结构 5.索引代码分析5.1 不同索引结构解析5.1.1…

郑州建站网页手机版

随着移动互联网的迅猛发展&#xff0c;越来越多的企业和个人开始重视手机网页的建设。在郑州&#xff0c;这一趋势尤为明显&#xff0c;搭建手机网页已经成为提升品牌形象和吸引客户的重要方式。本文将就郑州建站网页手机版的现状、重要性及注意事项进行探讨。 首先&#xff0c…

LabVIEW中升采样和降采样

升采样 (Upsampling) 和 降采样 (Downsampling) 是信号处理中的两种常见操作&#xff0c;用于改变信号的采样率。它们在数字信号处理&#xff08;DSP&#xff09;和许多工程应用中非常重要&#xff0c;尤其是在处理不同采样率的数据流时。 升采样 (Upsampling) 升采样是增加信…

SpringBoot 引入使用消息队列RabbitMQ通信 配置连接 无路由模式

介绍 请先对Rabbitmq的用户和权限配置好在进行往下的操作 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>下面将演示最简单的例子不过路由 生产者 -&g…

IDEA工程连接不上Mysql数据库

在进行项目创建的时候&#xff0c;发现IDEA工程连接不上数据库。即使登陆的用户名和密码全部正确也报错。 在服务里发现Mysql80没有启动 直接利用命令提示符启动&#xff0c;也显示启动失败。 通过 netstat -ano | findstr :3306 查看数据库默认端口3306的占用情况&#…

【CSP:202009-2】风险人群筛查(Java)

题目链接 202009-2 风险人群筛查 题目描述 求解思路 本题的数据量并不大&#xff0c;直接模拟即可。x和y表示每次读取的坐标点。res1表示经过高风险场地的人数&#xff0c;res2表示在高风险场地停留的人数。s用来记录连续在高风险场地停留的点数。r1表示是否经过高风险场地&…

【学习笔记】卫星通信NTN 3GPP标准化进展分析(三)- 3GPP Release17 内容

一、引言&#xff1a; 本文来自3GPP Joern Krause, 3GPP MCC (May 14,2024) Non-Terrestrial Networks (NTN) (3gpp.org) 本文总结了NTN标准化进程以及后续的研究计划&#xff0c;是学习NTN协议的入门。 【学习笔记】卫星通信NTN 3GPP标准化进展分析&#xff08;一&#xff…