进程间通信-管道

news2024/12/23 11:57:34

文章目录

  • 1. 进程间通信介绍
    • 1.1 进程间通信目的
    • 1.2 进程间通信分类
  • 2. 管道
    • 2.1 什么是管道
    • 2.2 站在文件描述符角度-深度理解管道
      • 2.2.1 具体通信的过程
    • 2.3 匿名管道
    • 2.4 代码实现
  • 3. 进程控制
  • 4. 管道读写规则
  • 5. 管道特点
  • 6. 命名管道
    • 6.1 创建一个命名管道
    • 6.2 代码实现

1. 进程间通信介绍

1.1 进程间通信目的

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

1.2 进程间通信分类

在这里插入图片描述
我们知道:进程是具有独立性的。如果我们想让进程之间交互数据,我们需要进程通信。而通信之前,我们最关键的是让不同的进程看到同一份资源。其实这里我们要学习的不是如何通信。而是如何看到同一份资源。由于资源的不同,决定了不同种类的通信方式

2. 管道

2.1 什么是管道

管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”
在这里插入图片描述

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

在这里插入图片描述
这是我们之前说的:一个进程打开文件的过程。现在我们想fork一下,那么它的子进程会拷贝哪些呢?答案是:子进程会拷贝父进程部分的PCB和struct file_struct,而不会拷贝struct file。而拷贝下来的子进程和父进程指向同一文件。
在这里插入图片描述
管道就是让写入的数据不在刷新到磁盘中,而是写入缓冲区中。所以,看待管道,就如同看待文件一样!管道的使用和文件一致,迎合了“Linux一切皆文件思想”。

那么管道具有什么特点呢
在进程间通信中,管道是用来传输数据的,并且是单向的

2.2.1 具体通信的过程

在这里插入图片描述
这里首先父进程是用两个文件描述符来打开管道的读和写。然后fork出子进程后,子进程也会指向同一个资源。如果父进程传数据给子进程,那么父进程会关闭读接口,子进程关闭写接口。反之,父进程会关闭写接口,子进程关闭读接口

现在有如下几个问题:
为什么父进程要分别打开读和写?
为了让子进程继承,那么子进程就不需要打开了

为什么父子要关闭对应的读或写?
因为管道是单向通信的

2.3 匿名管道

那么我们如何一次创建两个文件描述符来进行读和写呢
系统提供了我们一个接口:
在这里插入图片描述

2.4 代码实现

1. 创建管道:
在这里插入图片描述
2. 创建子进程:
在这里插入图片描述
3. 实现单向的:
现在我们需要子进程来进行只读,父进程只需要写。那么我们需要关闭子进程的写和父进程的读。
现在有一个问题是:数组里那个下标放的是读,那个放的是写
规定:下标0是读端,下标1是写端
在这里插入图片描述
验证一下是否通信
在这里插入图片描述
我们在父进程里写入一些变化的信息,然后通过管道让子进程去读。
在这里插入图片描述
这里有一个问题:子进程怎么知道父进程结束了
原因是:管道里有一个引用计数,可以知道有多少文件指向自己。当父进程写完时就会关闭文件描述符,管道里的引用计数就会减1

大家有没有想过这样的一个问题:父进程还没写完,子进程读完了?
答案是:这种情况在管道里不会发生。我们看下面的例子:
在这里插入图片描述
运行情况如下:
在这里插入图片描述
我们可以发现,子进程并没有去执行第二种情况。而是一直等待父进程。

结论:当父进程没有写入数据的时候,子进程在等。当父进程写入数据后,子进程才能read到数据。子进程打印读取数据要以父进程为主。父进程和子进程读写的时候,是有一定顺序性的

在父子进程向显示器写入时,就没有这样顺序。因为它们缺乏访问控制。管道内部,是自带访问控制机制。

管道内部,没有数据,read就必须阻塞等待(等管道有数据)。
管道内部,如果数据被写满,writer就必须阻塞等待(等待管道中有空间)

那么在命令行中的 | 这个管道是什么呢
其实就是匿名管道
在这里插入图片描述
在这里插入图片描述
我们可以看出管道两边的命令的ppid是一样的,也就是说它们的父亲是一样的。它们的关系是兄弟。

它是过程如下
在这里插入图片描述
这是一个创建子进程的管道,当我们再创建一个进程时。
在这里插入图片描述
再创建一个子进程后,父进程的读写端都关闭,然后让这两个兄弟进程通信。

3. 进程控制

现在,我们想控制进程做事情,我们这样写:
在这里插入图片描述
这个和上面是一样的,创建管道和创建子进程。
在这里插入图片描述
这里我们写一个函数集合,为了让子进程去执行这些方法。
在这里插入图片描述
这里写了一个子进程去执行任务的代码。

那么这个(void)s是什么意思呢
原因:assert断言,是编译有效,在debug模式下存在,release 模式,断言就没有了,一旦断言没有了,s变量就是只被定义了,没有被使用。release模式中,可能会有warning。
在这里插入图片描述
这是父进程指派任务的过程,父进程给子进程派送10次。

运行结果如下:
在这里插入图片描述

那么我们需要控制一批子进程呢
在这里插入图片描述
现在父进程要给三个子进程安排不同的任务,我们有什么解决办法呢?
在这里插入图片描述
有几个进程,我们创建几个管道。如果我们想让进程1做某些任务,我们就往1管道里面写,如果我们想让进程2做某些任务,我们就往2管道里面写,依次类推。

代码实现:
在这里插入图片描述
我们这里添加了一个pair类型的结构和进程的个数。

那么第一步:我们需要创建processNum个进程。
在这里插入图片描述
第二步:父进程给哪个进程指派任务。
在这里插入图片描述
这里父进程做的事,让子进程和对应管道写端的结构体放进这个数组里。这样就能知道哪个进程对应哪个管道。
在这里插入图片描述
当所有的子进程创建成功后,我们就开始让父进程来派发任务。

派发任务的代码我们如何写呢
在这里插入图片描述

第三步:子进程去执行任务。
在这里插入图片描述
那么我们就要完成这个work函数:
在这里插入图片描述
子进程在对应的blockFd去读。

第四步:回收资源。
在这里插入图片描述
运行结果如下
在这里插入图片描述

4. 管道读写规则

当没有数据可读时
O_NONBLOCK disable:read调用阻塞,即进程暂停执行,一直等到有数据来到为止。
O_NONBLOCK enable:read调用返回-1,errno值为EAGAIN。

当管道满的时候
O_NONBLOCK disable: write调用阻塞,直到有进程读走数据
O_NONBLOCK enable:调用返回-1,errno值为EAGAIN。

如果所有管道写端对应的文件描述符被关闭,则read返回0。
如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE,进而可能导致write进程退出。
当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。
当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性

5. 管道特点

  1. 只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信。通常,一个管道由一个进程创建,然后该进程调用fork,此后父,子进程之间就可应用该管道。
  2. 管道只能单向通信(内核实现决定的)。管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道。
    在这里插入图片描述
  3. 管道自带同步机制(pipe满,write等,pipe空,read等),也就是自带访问控制。
  4. 一般而言,进程退出,管道释放,所以管道的生命周期随进程。
  5. 管道是面向字节流的,先写的字符,一定是先被读取,没有格式边界,需要用户来定义区分内容的边界(比如:上面写的sizeof(uint32_t))。

6. 命名管道

管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。如果我们想在不相关的进程之间交换数据,可以使用命名管道

6.1 创建一个命名管道

命名管道可以从命令行上创建,命令行方法是使用下面这个命令:
在这里插入图片描述
在这里插入图片描述
命名管道也可以从程序里创建,相关函数有:
在这里插入图片描述
我们知道:进程间通信的本质是不同的进程看到同一份资源。匿名管道是通过子进程继承父进程的文件描述符表。命名管道是通过一个fifo文件,文件有路径,所有具有唯一性。所以通过路径我们可以找到同一份资源

6.2 代码实现

在这里插入图片描述
我们在这里创建两个文件,一个是客户端文件,一个是服务端文件。

首先,我们要让这两个进程看到同一份资源:
在这里插入图片描述
我们在这里创建了一个隐藏文件。在这个头文件里。然后我们让clientFifo文件和serverFifo文件都包含这个头文件,这样这两个进程都可以看到这个路径了。
在这里插入图片描述
这是makefile里面的代码,因为我们要形成两个可执行程序。

现在我们就需要创建管道文件,只需要一个进程创建管道文件,另外一个来使用这个就可以了。那么我们就在服务端创建这个管道文件:
在这里插入图片描述
我们先看一下运行结果:
在这里插入图片描述
从运行结果我们可以看到:创建了一个.fifo的文件。

现在我们想让clientFifo进程去写入,让serverFifo进程去读取:
在这里插入图片描述
首先,我们以写的方式打开文件,让管道的引用计数+1。

下面我们就要让它完成写入功能:
在这里插入图片描述
写完后进行关闭:
在这里插入图片描述
serverFifo也是类似的道理,我们以读的方式打开文件:
在这里插入图片描述
那么下面就是serverFifo读取的过程:
在这里插入图片描述
读取完之后,我们需要关闭:
在这里插入图片描述

运行结果:
在这里插入图片描述
在这里插入图片描述
从结果我们可以看到:在clientFifo里面写入,在serverFifo就能读取。
在这里插入图片描述
当clientFifo进程按Ctrl+d退出时,serverFifo也退出了,并且.fifo也自动删除。

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

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

相关文章

索引的底层数据结构,讲讲B+ 树,B树

B 树的变种。 B树:所有节点(非叶子节点 叶子节点),都存储真正的行数据,所以一个数据页能存储的数量,相较于 B 树,就少很多。 B 树: ● 只有叶子节点存储具体的行数据,非…

【进阶】C 语言表驱动法编程原理与实践

数据压倒一切。如果选择了正确的数据结构并把一切组织的井井有条,正确的算法就不言自明。编程的核心是数据结构,而不是算法。——Rob Pike 目录 说明 概念提出 查表方式 直接查找 索引查找 分段查找 实战示例 字符统计 月天校验 名称构造 值名…

Python——sentenceSimilarity 的简单demo(测试句子相似度)

一、sentenceSimilarity 是什么? sentenceSimilarity 属于机器学习的领域 Python 中的 sentenceSimilarity 库是一个用于计算句子相似度的工具库,主要用于自然语言处理相关的应用中。该库支持多种模型计算句子相似度,包括 TF-IDF、LSI、LDA 等…

MySQL进阶篇(三)

七.MySQL管理 7.1 系统数据库 Mysql数据库安装完成后,自带了一下四个数据库,具体作用如下: 7.2 常用工具 7.2.1 mysql 该mysql不是指mysql服务,而是指mysql的客户端工具。 -e选项可以在Mysql客户端执行SQL语句,而…

【Linux】Linux环境基础开发工具使用(yum和vim)

⭐博客主页:️CS semi主页 ⭐欢迎关注:点赞收藏留言 ⭐系列专栏:Linux ⭐代码仓库:Linux 家人们更新不易,你们的点赞和关注对我而言十分重要,友友们麻烦多多点赞+关注,你们的支持是我…

NSFW 图片分类

NSFW指的是 不适宜工作场所(“Not Safe (or Suitable) For Work;”)。在本文中,将介绍如何创建一个检测NSFW图像的图像分类模型。 数据集 由于数据集的性质,我们无法从一些数据集的网站(如Kaggle等)获得所有图像。 但是我们找到…

少儿编程 中国电子学会图形化编程等级考试Scratch编程四级真题解析(选择题)2023年3月

2023年3月scratch编程等级考试四级真题 选择题(共25题,每题2分,共50分) 1、编写一段程序,从26个英文字母中,随机选出10个加入列表a。空白处应填入的代码是 A、 B、 C、 D、 答案:C

[CTF/网络安全] 攻防世界 simple_php 解题详析

[CTF/网络安全] 攻防世界 simple_php 解题详析 代码解读PHP弱语言特性姿势参数a限制绕过参数b限制绕过 总结 题目描述:小宁听说php是最好的语言,于是她简单学习之后写了几行php代码。 代码解读 $a$_GET[a]; 从HTTP GET请求参数中获取一个名为a的变量&#xff0c…

协同过滤算法的召回率、准确率、覆盖率、新颖度

python版计算协同过滤推荐算法的召回率、准确率、覆盖率、新颖度 推荐算法网站示例Demo 点我跳转图书管理推荐系统 点我跳转课程推荐系统 点我跳转电影推荐系统 1、召回率、准确率 2、覆盖率、新颖度 覆盖率反映了推荐算法发掘长尾的能力,覆盖率越高,说明推荐算法越能够将…

ChatGPT开始颠覆学习方式,应试教育面临哪些挑战?

ChatGPT爆火几个月,整个教育系统都在被颠覆。全球范围内,不少大学教授、系主任和管理人员,都在对课堂进行大规模的调整,以应对ChatGPT对教学活动造成的巨大冲击。 国内传统应试教育选出的分霸、考霸,是更能吃苦&#…

c++中的方法

c中的方法 static方法 与数据成员类似,方法有时会应用于全部对象而不是单个对象。可以编写static方法和数据成员。在方法声明前加上static即可。对于方法的定义前则不需要重复使用static关键字。 class Foo { public:static int sumFunc(int a, int b); };int Fo…

康耐视Visionpro工具-CogPMAlignTool为什么是最牛工具?

1.算法:有六种选项,分别是:PatMax,PatQuick, PatMax 与 PatQuick, PatFlex,PatMax-高灵敏度,透视 Patmax。 PatQuick 特点:速度最快,对于三维或者低质量原件最佳,承受更多图像差异; PatMax 特点:精确度最高,在二维元件上表现佳,最适合于细微细节; PatFlex 特点…

4. 通讯录实现的需求分析和架构设计

本文实现的是通讯录产品的需求分析和架构设计,重点在于结构层次的设计,方便代码阅读和维护。 一、通讯录实现的需求分析 1、通讯录的功能清单 添加一个人员打印显示所有人员删除一个人员查找一个人员保存文件加载文件 2,数据存储信息 人员…

[CTF/网络安全] 攻防世界 disabled_button 解题详析

[CTF/网络安全] 攻防世界 disabled_button 解题详析 input标签姿势disable属性总结 题目描述:X老师今天上课讲了前端知识,然后给了大家一个不能按的按钮,小宁惊奇地发现这个按钮按不下去,到底怎么才能按下去呢? input标…

Tiny+ 语言词法之C语言

访问【WRITE-BUG数字空间】_[内附完整源码和文档] 语义分析本质上就是在语法分析的基础上进一步完善分析的功能。举个例子来说,在语法分析部分的 if_stmt 函数中,在语义上判断条件必须返回布尔类型的值,因此我们加入一个判断,判断…

Unity之OpenXR+XR Interaction Toolkit示例Demo详解

一.前言 自从升级Unity版本到2021,然后使用OpenXR开发VR之后,我们整个团队的开发效率都提升了不少,这证明了不管什么领域,统一接口,统一规范都是必须的。 关于XR Interaction Toolkit插件,我已经写了几篇文章了,今天才想起来,最基础的Demo讲解还没有写,其实官方的这个…

chatgpt赋能Python-pythonfor循环5次

Python中for循环的使用方法及技巧 Python作为一种高级编程语言,其独特的语法结构和方便的操作方法受到了越来越多人的欢迎和喜爱。其中,for循环是Python程序员必备的基本技巧之一。在这篇文章中,我们将介绍Python中for循环的使用方法及技巧。…

HTTP协议【面试高频考点】

目录 一、HTTP 响应 1.首行 2.状态码(经典面试题,必考) 2.1 200 OK 2.2 404 Not Found 2.3 403 Forbidden 2.4 500 Internal Server Error 2.5 504 Gateway Timeout 2.6 302 Move temporarily 2.7 301 Moved Permanently 2.8 状态…

clearmymac4.13.5专业的Mac系统清理优化工具

CleanMyMac X是一款功能强大的Mac清理工具,它可以扫描您的Mac电脑,清除垃圾文件,卸载无用的应用程序,并优化系统性能。此外,CleanMyMac X还可以找到和修复Mac电脑上的许多其他问题,即使您不是技术专家也可以…

chatgpt赋能Python-pythona__a

Python中的aa 介绍 Python是一种流行的编程语言,具有简单易学和可读性强的特点。在Python中,常常使用aa这样的表达式,它表示将变量a的原始值加上它自己的值,然后将结果赋值给变量a。这种语法看起来很简单,但实际上有…