【linux深入剖析】进程间通信


🍁你好,我是 RO-BERRY
📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油

在这里插入图片描述


目录

  • 1.进程间通信目的
  • 2. 什么是进程间通信
  • 3. 进程间通信发展
  • 4.如何进行进程间通信
    • 4.1 一般规律
    • 4.2 具体做法
  • 5.进程间通信分类
  • 6. 管道
    • 匿名管道
    • 用fork来共享管道原理
    • 站在文件描述符角度-深度理解管道
    • 验证管道通信代码


1.进程间通信目的

两个进程之间,可以进行“数据”的直接传递吗?不能!进程具有独立性

那么为什么需要进程间通信呢?

  • 数据传输:一个进程需要将它的数据发送给另一个进程

在很多场景之间,两个进程需要进行数据传输,比如:A进程负责获取网络中的数据,但是它并不会去处理这份数据,而B进程为只负责处理数据,这样就可以实现多进程的并发

  • 资源共享:多个进程之间共享同样的资源。

有一部分进程需要进行共享一份资源,以便于两进程共同访问共同完成一件事情,比如说:我们玩游戏,多玩家在同一局游戏中,我们看到的数据都是一模一样的,我们的每个用户也就是一个进程,我们对于地图资源进行的是共享

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

2. 什么是进程间通信

  • 进程间通信(Inter-process Communication,IPC)是指在多道程序环境下,进程间进行数据交换和信息传递的一种机制或方法。在现代操作系统中,进程是系统资源分配的基本单位,不同进程之间需要相互合作和通信,才能完成各种任务。进程间通信是实现进程间协作的重要手段。

  • 常用的进程间通信方式有管道、消息队列、共享内存、信号量和套接字等。管道是一种半双工的通信方式,消息队列是一种异步通信方式,共享内存是一种高效的通信方式,信号量是一种用于同步进程的通信方式,套接字是一种网络通信方式。


3. 进程间通信发展

进程间通信是指不同进程之间的数据交换和共享,是操作系统中非常重要的一个概念。随着计算机技术的发展,进程间通信也经历了多个发展阶段。

  • 第一阶段是管道,它是Unix系统中最早的进程间通信方式,可以在两个相关进程之间传递数据。

  • 第二阶段是信号,它是Unix系统中另一种进程间通信方式,用于通知接收进程某个事件已经发生。

  • 第三阶段是共享内存,它可以允许多个进程访问同一块物理内存,从而实现数据共享。

  • 第四阶段是消息队列,它可以在不同进程之间传递消息,实现进程间通信。

  • 第五阶段是套接字,它可以在不同主机之间传递数据,并且支持多种通信协议。

  • 第六阶段是远程过程调用(RPC),它允许程序员在不同计算机上运行的程序之间进行交互。


4.如何进行进程间通信

4.1 一般规律

  • 进程间通信的本质:让不同的进程,看到同一份资源(一般都是由OS提供)

进程间通信需要一个另外的交换数据的空间(内存)

此交换空间不能由通信双方任何一方进行提供,如果提供了空间,让对方进程来进行访问,这就有违背进程独立性,所以我们需要另一个额外空间进行数据的传输,这种事情会有OS来进行操作


4.2 具体做法

OS提供的“空间”有不同的样式,这决定了不同的通信方式

常见通信方式:

  1. 管道(匿名和命名)
  2. 共享内存
  3. 消息队列
  4. 信号量

5.进程间通信分类

🍁管道

  • 匿名管道pipe
  • 命名管道

🍁System V IPC

System V IPC是指System V操作系统提供的进程间通信(IPC)机制,它允许进程在不同的计算机系统之间进行通信和同步。System V IPC主要包括三种类型的通信机制:消息队列、共享内存和信号量。

  • System V 消息队列
  • System V 共享内存
  • System V 信号量

🍁POSIX IPC

POSIX IPC 是指可移植操作系统接口(Portable Operating System Interface,缩写为POSIX)中的进程间通信(Inter-Process Communication,缩写为IPC)机制。它提供了一组标准的函数和数据结构,用于在不同的进程间进行数据交换和同步操作。常用的 POSIX IPC 包括消息队列、共享内存、信号量等。使用 POSIX IPC 可以实现不同进程之间的数据共享和通信,进而实现更加复杂的多进程协作模式。

  • 消息队列
  • 共享内存
  • 信号量
  • 互斥量
  • 条件变量
  • 读写锁

6. 管道

  • 管道是Unix中最古老的进程间通信的形式。
  • 我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”

管道是一种进程间通信机制,它可以用来在不同进程间传递数据。在底层实现上,管道其实是一种内核缓冲区,它由两个文件描述符(文件句柄)表示,一个用于读取,一个用于写入。当一个进程向管道中写入数据时,数据会被存储到内核缓冲区中,另一个进程则可以从同一个管道中读取这些数据。

管道底层实现的关键是通过操作系统提供的内核缓冲区实现进程间的数据传输。管道有两个缓冲区,分别用于存储读取和写入的数据。当写入进程向管道中写入数据时,数据会被存储到写入缓冲区中。如果写入缓冲区已满,则写入进程会被阻塞,直到有足够的空间来存储数据。当读取进程从管道中读取数据时,数据会从读取缓冲区中读取。如果读取缓冲区为空,则读取进程也会被阻塞,直到有新的数据可供读取。

需要注意的是,管道具有单向性,即数据只能从一个方向流动。如果需要双向通信,则需要创建两个管道。同时,在管道中传递的数据是没有结构的字节流,因此需要约定好传递的数据格式以及数据长度。

匿名管道

#include <unistd.h>
功能:创建一无名管道
原型
int pipe(int fd[2]);
参数
fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
返回值:成功返回0,失败返回错误代码

这个函数让我们不需要向磁盘中刷新并且磁盘中并不存在文件,其本质就是会创建一个内存级的文件,这个文件没有名字,为匿名文件(管道)

匿名管道如何做到让不同的进程看到同一份资源?

就是利用了创建子进程,子进程会创建父进程的相关属性信息,匿名管道可以(只能)进行具有血缘关系的进程,进行进程间通信,常用于父子

在这里插入图片描述
实例代码

例子:从键盘读取数据,写入管道,读取管道,写到屏幕
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void)
{int fds[2];char buf[100];int len;if (pipe(fds) == -1)perror("make pipe"), exit(1);// read from stdinwhile (fgets(buf, 100, stdin)) {len = strlen(buf);// write into pipeif (write(fds[1], buf, len) != len) {perror("write to pipe");break;}memset(buf, 0x00, sizeof(buf));// read from pipeif ((len = read(fds[0], buf, 100)) == -1) {perror("read from pipe");break;}// write to stdoutif (write(1, buf, len) != len) {perror("write to stdout");break;}}
}

用fork来共享管道原理

在这里插入图片描述

站在文件描述符角度-深度理解管道

在这里插入图片描述

为什么父进程最开始就要按照r和w打开同一个文件呢?
这是因为管道只允许一个人读,一个人写。

验证管道通信代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>void writer(int wfd)
{const char *str ="hello father, I am child";char buffer[128];int cnt = 0;pid_t pid  = getpid();while(1){snprintf(buffer, sizeof(buffer),"message: %s,pid: %d,count: %d \n", str, pid, cnt);write(wfd,buffer,strlen(buffer)+1);cnt++;sleep(1);}
}
void reader(int rfd)
{char buffer[1024];while(1){ssize_t n = read(rfd, buffer, sizeof(buffer)-1);(void)n;   //读取但是没有用printf("father get a message: %s", buffer);}
}int main()
{int pipefd[2];int n = pipe(pipefd);if(n<0) return 1;printf("pipefd[0]: %d, pipefd[1]: %d\n", pipefd[0]/*read*/, pipefd[1])/*write*/; //创建管道//父子进程pid_t id=fork();if(id == 0){//child 实现W 关闭读取保留写入close(pipefd[0]);writer(pipefd[1]);exit(0);}//father实现rclose(pipefd[1]);reader(pipefd[0]);wait(NULL);return 0;
}

在这里插入图片描述
这里可以在左边看到有两个进程同时运行,初步实现管道通信,子进程可以写给父程序

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

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

相关文章

react 怎样向ant table添加按钮,以及文本溢出隐藏?

这些都是一些组件自带的方法&#xff0c;只不过是不知道该怎么用&#xff0c;上面的内容可以直接拿去用&#xff0c;&#xff08;事件除外&#xff0c;要自己绑&#xff0c;还有引入的组件&#xff09;&#xff01;

数据结构:栈和队列的练习题1(括号匹配问题)

题目描述&#xff1a; 思路&#xff1a;我们首先可以把出现的情况大致分为以下几类&#xff1a; 因为涉及匹配问题&#xff0c;所以所有的左括号和右括号肯定要分开来整理。如果我们直接去匹配的话&#xff08;像第一行的从左到右独立匹配&#xff09;是行得通的&#xff0c;但…

关于d3js生成节点画布的个人笔记

实现功能 根据鼠标位置生成节点根据节点位置通过鼠标拖拽生成连线实现自定义线段颜色功能删除节点以及连线功能实现单个节点拖动功能实现整条线路的拖动功能 界面如下&#xff1a; 主要模块介绍 绘制连线 const line svg.selectAll(".line").data(links, d >…

【Linux】Git超详细教程:手把手教你(gitee版)--版本管理+远程仓库克隆(初学者必看!!!)

目录 一、前言 二、git 的深度理解 &#x1f95d; 什么是 git ? &#x1f347; git 的历史发展&#xff08;理解 git 的由来&#xff09; &#x1f34b; 感性理解 git 的版本管理 三、git 的安装 ✨Window 终端安装 ✨Linux 安装 四、git 的工作流程 五、如何在 Linux …

音视频开发—视频相关概念:YUV与RGB

文章目录 YUV相关概念组成部分优点常见的 YUV 格式数据量的计算YUV4:2:0 存储格式平面模式&#xff08;planar):打包模式&#xff08;packed&#xff09; RGB 和 YUV 的定义关系与转换RGB 到 YUV 的转换YUV 到 RGB 的转换 使用场景优缺点 YUV相关概念 YUV 是一种颜色编码格式&…

JVM-JAVA-类加载过程

JVM源码 类加载到 JVM 的过程通过 java 命令执行代码的流程 类加载到 JVM 的过程 在运行一个 main 函数启动程序是&#xff0c;首先需要类加载起把主类加载到 JVM 中 通过 java 命令执行代码的流程 loadClass的类加载过程有如下几步&#xff1a; 类被加载到方法区中后主要包…

Maven项目通过maven central 发布到中央仓库 https://repo.maven.apache.org/ 手把手教学 最新教学

一、注册maven central账号 ​ https://central.sonatype.com/publishing/namespaces 我这里直接使用github账号登录 &#xff0c;可以自己注册或者直接使用google账号或者github账号登录 这里github账号登录之后 应该只出现io.github 下面的io.gitee我也验证过 所以这里出…

Java时间类--JDK8

为什么JDK8会又新增时间相关类呢&#xff1f; ① JDK7的时间对象如果需要比较大小的话&#xff0c;必须都先转换成毫秒值&#xff1b;JDK8则不需要&#xff0c;可以直接比较。 ② JDK7的时间对象可以修改&#xff0c;在多线程环境下就会导致数据不安全&#xff1b;JDK8不能修改…

输入3个字符串,要求将字母按由小到大顺序输出

对于将3个整数按由小到大顺序输出&#xff0c;是很容易处理的。可以按照同样的算法来处理将3个字符串按大小顺序输出。可以直接写出程序。 编写程序&#xff1a; 运行结果&#xff1a; 这个程序是很好理解的。在程序中对字符串变量用关系运算符进行比较&#xff0c;如同对数值…

【Git 版本管理】合并 + 变更,看懂Git

看懂 Git 合并操作分离 HEAD分离 HEAD 测试 相对引用(^ || ~)操作符 ^相对引用 ^ 测试操作符 ~相对引用 ~ 测试 撤销变更Git ResetGit Revert撤销变更 测试 整理提交记录Git Cherry-pick测试 交互式 rebase交互式 rebase 测试 合并操作 关键字&#xff1a;commit、branch、merg…

Minio篇:初识MinIO

1. MinIO快速入门 1.1.MinIO核心概念 下面介绍MinIO中的几个核心概念&#xff0c;这些概念在所有的对象存储服务中也都是通用的。 对象&#xff08;Object&#xff09; 对象是实际的数据单元&#xff0c;例如我们上传的一个图片。 存储桶&#xff08;Bucket&#xff09; 存储…

【JAVA SE】多态

✨✨欢迎大家来到Celia的博客✨✨ &#x1f389;&#x1f389;创作不易&#xff0c;请点赞关注&#xff0c;多多支持哦&#x1f389;&#x1f389; 所属专栏&#xff1a;JAVA 个人主页&#xff1a;Celias blog~ 目录 引言 一、多态 1.1 多态的概念 1.2 多态的实现条件 1.3…

深入探讨 Android 的 View 显示过程与源码分析

文章目录 1. 探讨 Android 的 View 显示过程1.1. onFinishInflate1.2. onAttachedToWindow1.3. onMeasure1.4. onSizeChanged1.5. onLayout1.6. onDraw 2. 系统代码分析1.1. onFinishInflate1.2. onAttachedToWindow1.3. onMeasure1.4. onSizeChanged1.5. onLayout1.6. onDraw …

数字化浪潮中的TPM革新:打造高效生产新范式

在数字化浪潮席卷全球的今天&#xff0c;传统生产管理模式正面临前所未有的挑战与机遇。TPM&#xff08;全面生产维护&#xff09;作为一种先进的生产管理理念&#xff0c;如何在数字化驱动下焕发新的活力&#xff0c;成为制造业转型升级的关键一环。 数字化技术为TPM带来了前…

探秘Flask中的表单数据处理

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、Flask中的表单处理机制 三、Flask表单处理实战 四、处理表单数据的注意事项…

为什么要使用动态代理IP?

一、什么是动态代理IP&#xff1f; 动态代理IP是指利用代理服务器来转发网络请求&#xff0c;并通过不断更新IP地址来保护访问者的原始IP&#xff0c;从而达到匿名访问、保护隐私和提高访问安全性的目的。动态代理IP在多个领域中都有广泛的应用&#xff0c;能够帮助用户…

vue路由跳转之【编程式导航与传参】

vue路由有两种跳转方式 ----> 编程式与声明式&#xff0c;本文重点讲解vue路由的【编程式导航 】【编程式导航传参 ( 查询参数传参 & 动态路由传参 ) 】等内容&#xff0c;并结合具体案例让小伙伴们深入理解 &#xff0c;彻底掌握&#xff01;创作不易&#xff0c;需要的…

2023年全球DDoS攻击现状与趋势分析

天翼安全科技有限公司副总工程师、运营保障部总经理陈林表示&#xff0c;2023年扫段攻击频次快速增长&#xff0c;成为网络基础设施面临的最大威胁。为躲避防御&#xff0c;低速扫段攻击成为主流达到攻击总数的73.19%&#xff1b;43.26%的C段攻击持续时间小于5分钟&#xff0c;…

Linux中部署MinIO

Linux中部署MinIO 下载MinIO可执行程序&#xff1a; wget https://dl.min.io/server/minio/release/linux-amd64/minio 添加执行权限&#xff1a; chmod x minio 创建存储目录&#xff0c;例如/data&#xff1a; mkdir -p /data 运行MinIO服务器&#xff0c;需要设置MIN…

【设计模式】JAVA Design Patterns——Factory Method(虚拟构造器模式)

&#x1f50d;目的 为创建一个对象定义一个接口&#xff0c;但是让子类决定实例化哪个类。工厂方法允许类将实例化延迟到子类 &#x1f50d;解释 真实世界例子 铁匠生产武器。精灵需要精灵武器&#xff0c;而兽人需要兽人武器。根据客户来召唤正确类型的铁匠。 通俗描述 它为类…