进程通信(管道,共享内存实现)

news2025/5/27 12:51:13

01. 进程通信简介

进程通信工具分为数据传输工具和共享内存两类。这里我们讨论进程通信工具(IPC)里面的管道、system V和共享内存。在理解阶层通信之间,我们先了解用户空间缓冲区和内核空间缓冲区两个概念。

在这里插入图片描述

1.1 用户空间缓冲区

存在于用户态的进程用户空间,进程直接读取。用于存储待发送或已接收的数据,减少频繁的系统调用开销。

代码示例:

char buf[1024];
write(fd, buf, sizeof(buf));  // 将用户缓冲区buf数据写到fd指向内核
read(fd, buf, sizeof(buf));  // 从内核读取数据到用户缓冲区

**PS:**可以使用 fnprintf 先写入用户缓冲区,满后再通过 write 系统调用写入内核(后面有提到)。


1.2 内核空间缓冲区

存在于内核态作为管道通信的中转站,操作系统进行管理,使用系统调用访问


02. 管道(pipe)

我们再使用Linuxls | wc -l命令时,会用到 |这个符号表示的即是一个管道。为了执行这么命令创建了两个进程分别执行lswc

在这里插入图片描述

2.1 管道特点

为了通信,一个进程从用户内存向内核内存(进程通信)工具中写入数据,另外一个进程从内核内存读取数据到用户内存,这样便完成了数据的写入和读取,两个过程不能同时进行,且有以下要求:

  • 血缘关系:仅适用于有共同祖先(血缘关系)的进程;通常,一个管道由一个进程创建,然后该进程调用fork(),此后父、子进程之间就可应用该管道(下方有涉及)
  • 内核缓冲区:数据通过内核缓冲区传输,默认大小通常为4KB
  • 阻塞机制:当管道为空时,读操作阻塞;当管道满时,写操作阻塞;进程退出,管道释放
  • 半双工:数据只能单向流动若需双向通信,需创建两个管道

在这里插入图片描述

用户进程 用户缓冲区 内核管道缓冲区 准备数据(如 snprintf) write(fd, buf, sizeof(buf)) 返回实际写入字节数 read(fd, buf, sizeof(buf)) 填充数据 处理数据(如 printf) 用户进程 用户缓冲区 内核管道缓冲区

2.2管道的创建和使用

int pipe(int pipefds[2])
    //成功返回0,失败返回-1并且errno报错

pipe()系统调用创建一个新管道。成功的pipe()调用会在pipefds数组中返回两个打开的文件描述符:pipefds[0]表示读取端,pipefds[1]表示写入端。可以使用 read()和 write()系统调用来在管道上执行 I/O。一旦向管道写入数据之后立即就能从管道的读取端读取数据。但当管道为空时阻塞read()调用读取的是min{请求的字节数,当前管道存在字节数}。

在这里插入图片描述

2.2.1 匿名管道

父子进程通信过程:

  1. 父进程创建管道,得到两个⽂件描述符指向管道的两端

  2. 父进程fork出子进程,⼦进程也有两个⽂件描述符指向同⼀管道

  3. 子进程关闭pipefds[0]读端,父进程关闭pipefds[1]写端即可实现了进程间通信

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
int main()
{
    int pipefds[2] = {0};
    int n = pipe(pipefds);
    assert(n == 0)
        // 0:读取端  1:写入端
        pid_t id = fork();
    	assert(id >= 0) ;
    	if (id == 0)
        {                      // 子进程写入
        close(pipefds[0]); // 子进程关闭读端
        const char *msg = "hello Linux!";
        int cnt = 0;
        while (1)
        {
            char buf[1024];
            fnprintf(buf, sizeof buf, "child is sauing:%s[%d] ", msg, cnt);
            write(pipefds[1], buf, strlen(buf));
            sleep(1);
        }
        exit(0);
    }
    // 父进程读取
    close(pipefds[1]); // 父进程关闭写端
    while (1)
    {
        char buf[1024];
        ssize_t s = read(pipefds[0], buf, sizeof(buf) - 1); // 保证从二进制文件读取到用户进程某位空一个\0
        if (s == 0)
        { // 意味着子进程退出了
            printf("child quit\n");
            break;
        }
        else if (s > 0)
        {
            buf[s] = 0;
            printf("child say to father# %s\n", buffer);
        }
        else
        {
            printf("read error\n");
            break;
        }
    }
    return 0;
}

加载中...
父子进程读取和写入分别在文件描述符中fd[3]fd[4],然后子进程为了写入关闭fd[3],父进程为了读取则需要关闭fd[4]

2.2.2 命名管道

system V共享内存

即允许一个进程将数据放到进程共享内存块中让其他进程读取这些数据来完成信息交换,此过程不涉及变换状态(内核态和用户态切换),使其速度非常快。

system V共享内存

即允许一个进程将数据放到进程共享内存块中让其他进程读取这些数据来完成信息交换,此过程不涉及变换状态(内核态和用户态切换),使其速度非常快。

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

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

相关文章

电池预测 | 第28讲 基于CNN-GRU的锂电池剩余寿命预测

电池预测 | 第28讲 基于CNN-GRU的锂电池剩余寿命预测 目录 电池预测 | 第28讲 基于CNN-GRU的锂电池剩余寿命预测预测效果基本描述程序设计参考资料 预测效果 基本描述 电池预测 | 第28讲 基于CNN-GRU的锂电池剩余寿命预测 运行环境Matlab2023b及以上&#xff0c;锂电池剩余寿…

快速上手SHELL脚本常用命令

一、设置主机名称 1.修改文件方式 重启后生效 2.命令修改 重启shell后生效 二、网卡管理nmcli 1.查看网卡 2.设置网卡 详细配置&#xff1a;快速上手Linux联网管理-CSDN博客 三、简单处理字符 1.打印连续数字 2.设置字体颜色 \033[颜色代号m 3.反向打印文件内容 tac&a…

【自然语言处理与大模型】大模型Agent四大的组件

大模型Agent是基于大型语言模型构建的智能体&#xff0c;它们能够模拟独立思考过程&#xff0c;灵活调用各类工具&#xff0c;逐步达成预设目标。这类智能体的设计旨在通过感知、思考与行动三者的紧密结合来完成复杂任务。下面将从大模型大脑&#xff08;LLM&#xff09;、规划…

小巧高效的目录索引生成软件

软件介绍 本文介绍的软件名为Snap2html&#xff0c;是一款树形目录索引生成工具。 软件大小与便捷性 Snap2html这款软件已完成汉化&#xff0c;其体积仅170kb&#xff0c;小巧无比&#xff0c;且无需安装&#xff0c;可直接投入使用。 软件使用方法 该软件操作简便&#xf…

云原生架构设计相关原则

文章目录 前言云原生架构概述云原生架构的核心原则一切皆服务原则自动化原则韧性和容错原则可观测性原则 云原生架构原则的实践意义 前言 大家好&#xff0c;我是沛哥儿。今天想和大家深入探讨一下云原生架构的相关原则。在如今数字化飞速发展的时代&#xff0c;云原生架构已经…

华为云Flexus+DeepSeek征文 | Flexus X实例助力 Dify-LLM 一键部署:性能跃升与成本优化的革新实践

引言 在AI大模型应用快速普及的背景下&#xff0c;企业对低门槛部署、高性能算力与成本可控的需求日益迫切。华为云推出的Flexus X实例&#xff0c;作为专为AI工作负载优化的新一代算力底座&#xff0c;通过1.6倍算力提升、关键业务6倍加速、综合降本30%等核心优势&#xff0c…

数据库blog7_MySql的下载与配置准备

&#x1f33f;MySql下载 &#x1f342;1.应用版本选择 选择社区版&#xff0c;免费适合初学者 相关链接下载页面下载界面介绍 &#x1f342;2.OS版本选择 根据自己的OS类型&#xff08;Windows/Linux&#xff08;CentOS/Ubuntu …&#xff09;/macOS&#xff09;选择对应版本…

YOLOv11助力地铁机场安检!!!一键识别刀具

文末有完整代码出处 随着现代社会的高速发展&#xff0c;交通工具和公共场所的安全管理面临着前所未有的挑战。尤其在机场、地铁、车站等公共安全检查点&#xff0c;如何提高安检效率、精准识别危险物品&#xff0c;成为了亟待解决的问题。在传统的安检过程中&#xff0c;X光图…

RFID工业读写器的场景化应用选型指南

RFID工业读写器是上海岳冉RFID专为工业场景设计的高性能射频识别设备&#xff0c;核心功能围绕高效数据采集与可靠传输展开。其基础能力包括多协议支持&#xff08;如ISO 18000-6C&#xff09;与多标签防碰撞处理&#xff0c;可同时读取/写入EPC编码、用户数据等标签信息&#…

单片机如何快速实现查看实时数据

在用 Keil 做调试的时候&#xff0c;最让人头秃的是什么&#xff1f; 不是写代码的BUG&#xff0c;而是&#xff1a;这个条件变量是什么情况&#xff1f;为什么没进入这个判断&#xff1f;我代码跑到哪里了&#xff1f; 其实本质上都是通过变量判断代码的执行顺序有没有问题 …

go实现钉钉三方登录

钉钉的的官方开发文档中只给出了java实现三方登录的&#xff0c;我们准备用go语言来实现 实现网页方式登录应用&#xff08;登录第三方网站&#xff09; - 钉钉开放平台 首先就是按照文档进行操作&#xff0c;备注好网站的信息 获得应用凭证&#xff0c;我们后面会用到 之后…

物流配送优化实战:用遗传算法破解选址难题

在电商与供应链高速发展的今天&#xff0c;物流配送成本优化始终是企业竞争力的核心议题之一。想象一下&#xff0c;当你面对 20 个分布在不同坐标的客户点、7 个可选配送中心和 1 个发件网点时&#xff0c;如何用最省钱的方式完成配送&#xff1f;今天我们就来拆解一个真实的物…

Linux 个人用户设置账号密码环境变量,四种方式

一、需要明白以下2点&#xff1a; 1、Linux 的环境变量是保存在变量 PATH 中&#xff0c;可通过 Linux shell 命令 echo $PATH 查看输出内容&#xff0c;或者直接输入 export 查看&#xff0c;或者输入 env 查看 2、Linux环境变量值之间是通过冒号进行隔开的( : ) 格式为&am…

Three.js搭建小米SU7三维汽车实战(5)su7登场

汽车模型加载 我们在sktechfab上下载的汽车是glb的文件格式&#xff0c;所以使用gltfLoader进行加载。这里将小车直接加载进来看看效果&#xff1b; import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js"; ....其余代码省略 const gltfLoader new GLT…

格恩朗管段超声波流量计:流量测量先锋

在流量测量技术不断迭代的浪潮中&#xff0c;格恩朗自 2019 年创立起&#xff0c;便以开拓者的姿态投身其中&#xff0c;致力于为全球用户提供先进、精准的流量测量解决方案。其旗下的管段超声波流量计&#xff0c;一经推出&#xff0c;便迅速吸引了行业的目光&#xff0c;成为…

图论 判断是否有环

前言&#xff1a;有点忘记是怎么判断一个图中是否是有环 如果是一个无向图&#xff0c;其实可以直接dfs&#xff0c;加上一个vis数组来一起判断 如果是有向图呢&#xff0c; class Solution:def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool…

EasyDarwin的配置与使用

一.语言配置 准备go语言 All releases - The Go Programming Language 增加系统环境变量 让其生效 二.项目配置 Clone项目并解压 git clone https://github.com/EasyDarwin/EasyDarwin.git cd EasyDarwin go mod tidy 紧接着 make build/linux cd build cd EasyDarwin-lin-&qu…

【Android】基于SurfaceControlViewHost实现跨进程渲染

1 前言 本文将介绍基于 SurfaceControlViewHost 实现跨进程渲染普通 View 和 GlSurfaceView&#xff0c;力求用最简单的 Demo&#xff0c;介绍 SurfaceControlViewHost 的应用&#xff0c;方便读者轻松扣出核心代码应用到自己的业务中。 核心代码片段如下。 1&#xff09;服务端…

vue+ThreeJs 创造自动选择的甜甜圈(圆环)

嗨&#xff0c;我是小路。今天主要和大家分享的主题是“vueThreeJs 创造自动选择的甜甜圈”。 一个漂浮在页面中央的 3D 圆环&#xff0c;多个图标/文本/图片均匀分布在圆周上。它会自动缓慢旋转&#xff0c;形成动态视觉焦点。这就是今天要搭建的项目&#xff0c;并对…

能说一下JVM的内存区域吗

根据Java虚拟机的规范&#xff0c;JVM的内存区域可以细分为程序计数器、虚拟机栈、本地方法栈、堆和方法区。 其中方法区和线程是共享的&#xff0c;虚拟机栈、本地方法区和程序计数器是线程私有的。 介绍一下程序计数器&#xff1f; 程序计数器也被称为PC寄存器。是一块较小…