Linux(15)——进程间通信

目录

一、进程间通信的介绍

✍️进程间通信的目的

✍️进程间通信的本质 

进程间通信的分类

✍️管道

✍️System V IPC

✍️POSIX IPC

二、管道 

🧠什么是管道

✍️匿名管道

📝匿名管道的原理

📝pipe函数

📝匿名管道的使用步骤 

​编辑📝管道读写的规则 

📝管道的特点 


一、进程间通信的介绍

✍️进程间通信的目的

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

✍️进程间通信的本质 

进程间通信的本质就是让不同的进程看到同一份资源

这里要解释一下了,由于进程具有独立性,所以想要直接实现不同进程间的相互通信还是非常困难的。

这里我们就引入了第三方资源来作为不同进程之间通信的桥梁,也就是说这些进程可以通过向这么个第三方资源进行写入和读取来进行通信,示意图如下:

通过上面的方式,我们就实现的不同进程看到了同一份资源,所以说进程间通信的本质就是让不同的进程看到了同一份资源。

进程间通信的分类

✍️管道

  • 匿名管道
  • 命名管道

✍️System V IPC

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

✍️POSIX IPC

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

二、管道 

🧠什么是管道

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

我们之前在谈Linux的命令的时候也提及了管道这一概念:

例如,这个查看当前服务器有多少用户登录的命令

我们发现这个命令是由who命令和wc命令组成的,这个命令运行起来之后就变成了两个进程了,who进程把执行得到的结果通过标准输出写入到了管道之中,wc进程通过标准输入从管道中读取数据,处理完之后再把结果通过标准输出给到用户。

注意:who显示的是相关信息,wc -l命令是用来统计行数的。

✍️匿名管道

📝匿名管道的原理

匿名管道用于进程间的通信,且仅限于父子进程之间的通信。

我们之前也说了,进程间通信的本质就是让不同的进程看到了同一份资源,使用匿名管道实现通信的原理就是让父子进程看了同一份被打开的文件资源,然后父子进程就可以对同一份资源进行读写操作,从而实现了进程间的通信。

敲黑板:

这里需要注意的是这里打开的文件是由操作系统来进行管理的,父子进程进行读写时并不会进行写时拷贝。

📝pipe函数

我们可以使用pipe函数来创建匿名管道

int pipe(int pipefd[2]);

参数说明:输入的参数实际上是输出型的参数,数组中的两个元素分别指向读端和写端。‘

  • pipefd[0]:管道读端的文件描述符
  • pipefd[1]:管道写端的文件描述符 

如果创建失败则返回-1,成功创建则返回0。

📝匿名管道的使用步骤 

我们在使用管道通信的时候,既要使用fork函数来创建子进程,也要使用pipe函数来创建管道。

第一步:父进程创建管道

第二步:父进程创建子进程

第三步:父端关闭写,子端关闭读

敲黑板:

这里的通信只能是单向的,也就是我们说的半双工,在代码中的反应就是管道只开一个读端和写端。

我们这里可以将上面的三个步骤再细化一下:

第一步:父进程创建管道

第二步:父进程创建子进程

第三步:父进程关闭写端,子进程关闭读端 

我们来写个代码演示一下:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>int main() {int fd[2] = {0}; // 作为pipe函数的参数来进行传递if(pipe(fd) < 0) {perror("pipe");exit(1);}pid_t id = fork();if(id == 0) // 子进程{close(fd[0]); // 关闭了读端const char* message = "Hello my father, I am child...";int count = 10;while(count--) {write(fd[1], message, strlen(message)); // 字节流的写入数据sleep(1);}close(fd[1]);exit(0);}// 父进程close(fd[1]); // 关闭了写端char buffer[64];while(1) {ssize_t s = read(fd[0], buffer, sizeof(buffer)); // 由于休眠时间的存在,就会读完整if(s > 0) {buffer[s] = '\0';printf("child send to father: %s\n", buffer);}else if (s == 0) {printf("the end\n");break;}else {printf("read error\n");break;}}close(fd[0]);waitpid(id, NULL, 0);return 0;
}

📝管道读写的规则 

pipe2函数的操作和pipe函数类似,具体的函数原型如下:

int pipe2(int pipefd[2], int flags);

pipe函数的第二个参数用来设置选项可以设置为O_NONBLOCK ,也就是非阻塞:

  1. 默认不传参数时,read在没有数据会一直等待数据的到来,write在数据数据写满的时候会等待数据被读走。
  2. 在加了O_NONBLOCK 参数的时候,read在没有数据的时候会返回-1,并把erron的值设置为EAGIN,write在数据写满的时候也会返回-1,并把erron的值设置为EAGIN。
  • 如果所有管道写端对应的文件描述符被关闭,则read返回0
  • 如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE,进而可能导致write进程退出
  • 当要写入的数据量不大于PIPE_BUF时,Linux将保证写入的原子性。
  • 当要写入的数据量大于PIPE_BUF时,Linux将不再保证写入的原子性。 

📝管道的特点 

第一点:管道内自带了同步和互斥机制

首先我们要知道什么是同步和互斥:

同步:两个或者是两个以上的进程在运行时要按照之前约定好的顺序依次执行,可以类比到做菜的场景,我们要先切菜洗菜才能去炒,要有一个先后的顺序才行。

互斥:防止多个进程同时操作了同一个资源,可以类比到打印的场景,A和B都要使用打印机打印,但是我们不能同时发送内容到打印机,否则就是打印出来的结果出错。

我们仔细思考会发现两者其实是类似的,同步是一种更加复杂的互斥,而互斥则是一种特殊的同步,对于我们的管道而言,互斥就是两个进程不可以同时对管道进行操作,他们会相互排斥,而同步也说的是不能对管道进行操作,但这里的要求是必须要是按照一定的次序来对管道进行操作的。

第二点:管道的生命周期随进程

管道的本质就是通过文件来进行通信的,也就是说管道是依赖于文件系统的,那么当所有的文件都退出了,文件也就被释放掉了,所一说管道的生命周期是随进程的。

第三点:管道提供的是流式服务

对于进程A写入管道的数据,进程B每次都可以从管道中任意读取数据,这种方式被称之为流式服务,与之对应的就是数据报服务,也就是后面我们会讲的字节流和数据包。

  • 流式服务:数据没有明确的分割,也就是会粘连在一起。
  • 数据报服务:数据有了明确的分割了,数据是一份一份的。

第四点:管道是半双工通信

在数据通信中,数据在线路上的传送方式有以下这几种:

1、单工通信:数据的传输是单向的。通信双方中,一方是发送端,一方是接受数据端。

2、半双工通信:半双工是指既可以从从两个反向上面通信,但是不可以同时通信。

3、全双工通信:全双工就是两个反向上可以同时通信,也就是加强版的半双工,双倍的单双工。

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

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

相关文章

【Flutter】双路视频播放方案

最近在做双路视频播放&#xff0c;就是在一个页面播放两个视频。我遇到的问题就是音频焦点冲突问题&#xff0c;在下面说明。什么是双路视频播放&#xff08;来自AI&#xff09;双路视频播放&#xff08;Dual-Video Playback&#xff09;&#xff0c;从字面上理解&#xff0c;就…

笔试——Day25

文章目录第一题题目思路代码第二题题目&#xff1a;思路代码第三题题目&#xff1a;思路代码第一题 题目 笨小猴 思路 模拟 统计每个字符出现的次数&#xff0c;用最大减最小&#xff0c;判断是不是质数&#xff1b; 质数的判断使用试除法&#xff1b; 代码 第二题 题目&…

【C#学习Day15笔记】拆箱装箱、 Equals与== 、文件读取IO

前言在C#第15天的学习中&#xff0c;我深入探索了类型转换机制、对象比较原理和文件操作技术三大核心主题。这些知识是构建高效、健壮程序的关键基础。本文完整保留我的课堂实践代码和命名体系&#xff0c;通过结构化梳理帮助大家掌握这些核心概念。所有代码示例均来自我的实际…

发电类电力业务许可证申请条件

基本条件&#xff1a;法人资格&#xff1a;申请人必须是依法注册的企业法人。 财务能力&#xff1a;应具有与所申请从事的电力业务相适应的财务能力。 专业人员要求&#xff1a;生产运行负责人、技术负责人、安全负责人和财务负责人需具备至少3年以上与申请从事的电力业务相关的…

JavaScript 高效入门指南:从基础到实战(VSCode 版)

废话不多说&#xff0c;直接上干货&#x1f600; 一、先搞定工具&#xff1a;VSCode 配置成「JS 开发神器」 工欲善其事&#xff0c;必先利其器。用 VSCode 写 JavaScript&#xff0c;这几个配置能让你效率翻倍&#xff1a; 1. 必装插件&#xff08;直接在 VSCode 插件商店搜…

《人形机器人的觉醒:技术革命与碳基未来》——类人关节设计:柔性驱动革命之液压人工肌肉

目录&#xff1a;一、人工肌肉的种类及人形机器人适用情况二、人形机器人用人工肌肉科研机构及其最新成果进展三、液压人工肌肉种类及工作机制四、液压人工肌肉适用人形机器人的性能要求和局限性五、液压人工肌肉材料技术进展及其限制与突破六、波士顿动力Spot的液压静液传动系…

26数据结构-顺序表

&#x1f4cc;有序顺序表的合并 #define MAX_SIZE 20 struct SeqList {int data[MAX_SIZE];int length; }; void mergeArray(SeqList &L1,SeqList &L2,SeqList &L) {int i0,j 0;while(i<L1.length && j<L2.length){if(L1.data[i]<L2.data[j])L.da…

25电赛e题 控制激光开关电路

e题明确说了禁止使用继电器控制&#xff0c;所以需要自己搭建一个mos管控制电路这里使用mos管来驱动GPIO → 电阻(220Ω) → MOSFET栅极(如IRF520N)MOSFET漏极接激光器正极MOSFET源极接地激光器负极直接接电源连接方式如下这里r36为栅极电阻&#xff0c;需要跟你们使用的mos配合…

ubuntu apt源报错?

报错原因&#xff1a;一、网络连接方面1.网络不通畅&#xff08;常见&#xff09;简单来说就是你的虚拟机连不上网&#xff0c;这时候你应该检查自己的ip 是不是dhcp自动获取的&#xff0c;或者你的网络配置是否有误。2.DNS 解析故障&#xff1a;DNS 服务器配置错误或 DNS 服务…

Scene as Occupancy

OccNet https://github.com/OpenDriveLab/OccNet Scene as Occupancy 提出了一种新的场景表示方法&#xff0c; 利用环视摄像头&#xff0c;采用级联和时序体素编码的方式来重建三维Occ场景。Method 1&#xff09;提出的OCCNet首先重建占据描述符&#xff0c;目标是为支持下游任…

Linux基础复习:字符输入与输出

该文仅针对自身对Linux基础知识不足的地方进行补充扩展&#xff0c;便于巩固。终端的输入和输出由字符设备管理。1、查看当前字符设备# 查看当前bash进程 [rootopenEuler-1 ~]# psPID TTY TIME CMD9662 pts/1 00:00:00 bash9938 pts/1 00:00:00 ps# 该目录存放了…

【初识数据结构】CS61B中的基数排序

本教程介绍 CS61B 中的基数排序&#xff0c;这是一种可以在某些情况下甚至超越归并排序、快速排序的特殊的排序方法&#xff0c;但是牺牲了内存空间计数排序 连续编号情形 我们需要对一个编号从 0 到 11 的表进行排序实际上我们可以拿出另一张同样大小的空白表&#xff0c;在遍…

ReAct模式深度解析:构建具备推理能力的AI智能体架构

本文深入剖析ReAct(Reasoning+Acting)架构设计模式,揭示如何通过推理与行动循环构建具备自主决策能力的AI智能体,并展示其在复杂问题求解中的革命性突破。 引言:从工具调用到自主决策的进化 传统AI系统面临的核心瓶颈: #mermaid-svg-orlnKyviyW86xIJZ {font-family:&quo…

Corrosion2靶机攻略

第一步搭建环境 靶机下载地址&#xff1a;https://download.vulnhub.com/corrosion/Corrosion2.ova 下载完成后直接右击用VM打开&#xff0c;重试一下就可以了 右击虚拟机设置将网络连接改成nat模式 第二步信息收集 查看一下靶机的网段&#xff0c;左上角编辑&#xff0c;虚…

SSL 剥离漏洞

一、SSL/TLS 协议基础​1.1、SSL/TLS 协议的核心功能​SSL/TLS 协议的核心功能主要包括三个方面&#xff1a;加密、认证和完整性校验&#xff0c;这三大功能共同构建了网络通信的安全屏障。​&#xff08;一&#xff09;加密​加密是 SSL/TLS 协议最基本的功能。它通过使用对称…

c++-reverse_iterator

C反向迭代器 反向迭代器是C标准库提供的一种适配器&#xff0c;它允许我们以相反的顺序遍历容器&#xff0c;反向迭代器是正向迭代器的封装。 迭代器可以分为两类&#xff1a;方向性质&#xff1a;单向迭代器&#xff08;Forward Iterator&#xff09;双向迭代器&#xff08;Bi…

linux内核驱动:电流/电压/功率监控模块INA226调试

目录背景一、芯片介绍二、手册三、内核驱动配置3.1 设备树配置3.2 修改内核配置文件3.3 编译四、内核驱动分析1、初始化流程2、属性文件/解释五、调试和计算背景 最近调试了一款德州仪器的带有I2C控制接口的可以实现电压、电流、功率监测&#xff0c;并可以进行报警设置的芯片I…

ACL 2024 大模型方向优秀论文:洞察NLP前沿​关键突破

关注gongzhonghao【计算机sci论文精选】近年来&#xff0c;以Transformer架构为核心的大语言模型重塑了自然语言处理领域的技术范式。当前ACL相关研究呈现多维度深化态势&#xff0c;从开源社区推动轻量化架构与低成本训练技术革新&#xff0c;到学术界探索检索增强等机制突破长…

乐创E20H1型IO从站与Ethercat转Profinet网关转换器的配置应用案例

本案例聚焦于西门子 1200PLC 与 E20H1 - T01 IO 从站的连接。在正常运行过程中&#xff0c;E20H1 - T01 IO 从站需支持 EtherCAT 协议&#xff0c;作为 EtherCAT 从站&#xff1b;而监控系统所采用的西门子 S7 - 1200 系列 PLC 则支持 PROFINET 协议。由于协议的不一致性&#…

【2】专业自定义图表创建及应用方法

一、专业自定义图表创建及应用方法1&#xff09;不是图表的图表制作方法例题1:迷你图表制作方法&#xfeff;定义&#xff1a;指依靠Excel基本制图功能之外的其他功能&#xff08;如公式、条件格式、迷你图等&#xff09;创建的数据可视化图表特点&#xff1a;引用数据少且占用…