【Linux】进程间通信——匿名管道|命名管道

目录

什么是进程间通信

管道

匿名管道


什么是进程间通信

进程间通信,顾名思义就是两个进程互相通信。

可是进程是独立的,该如何通信呢?

类比你和你的朋友在网上聊天,你们两个人也是独立的,是如何通信的呢?因为你能看到你朋友给你发的消息,你朋友也能看到这份消息。这个消息就是一个公共的资源。

所以进程间如果要进行通信,就需要两个进程看到同一份资源。

那么,通信的地点在哪里呢?

很明显,因为进程之间是独立的,所以通信的地点肯定不能在进程中,只能在操作系统中。

结论:进程间通信的地点是操作系统。

进程间通信的方式有很多,一般有三种:

1.管道:通过文件系统通信。

  • 匿名管道
  • 命名管道

2. system V:聚焦在本地通信

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

3. POSIX:让通信可以跨主机。

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

本文主要讲管道的通信方式。

管道

回顾文件系统

当父进程打开一个文件时,创建了一个子进程。子进程会继承父进程,包括继承父进程的文件描述符。子进程和父进程相同的fd指向同一个文件。

到这里,通信的条件就具有了,因为父子进程看到了同一份文件。

说明:在冯诺依曼体系结构中,磁盘是外设。而外设的读取速度是比较慢的。但是在进程间通信时,他们并不关心磁盘中有什么文件 - - - 说白了就是不会和磁盘进行交互。于是为了提升效率,就直接关闭了和磁盘中文件的交互。所以,这种不进行IO通信的文件,叫做内存级文件

那么,如果是内存级文件,需要如何进行通信呢?

1.父进程将内容写入到内存(struct file的内存缓冲区)中,

2.子进程从内存(struct file的内存缓冲区)中读取数据。

总共发生两次拷贝

结论:通过文件系统提供公共资源的进程间通信,叫做管道。

匿名管道

理论

定义:匿名管道,就是没有名字的管道。

使用范围:只能子在父子之间,或者父亲的所有孩子(兄弟)之间进行通信,也就是具有血缘关系才能通信。

原理:

第一步:父进程打开管道

从图中可以看到,fd[0]对应的是读端,对应父进程的3号文件描述符,

fd[1]对应的是写端,对应父进程的4号文件描述符。

fd[0]就是读端   fd[1]就是写端

第二步:父进程创建子进程,子进程会继承父进程的文件描述符

到这里,父子进程通信的管道(途径)就建立好了,但是管道就像水管一样,只能单向通信。所以,我们如果想要父进程写入,子进程读取,就需要关闭父进程的读端,子进程的写端。

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

实践

查看手册,查找pipe函数。

解读:pipe函数的形参是一个pipefd[2]的数组,该数组有两个元素,分别是fd[0]和fd[1];其中,pipefd[0]代表读端,pipefd[1]代表写端。

返回值:如果创建成功,返回0,否则返回-1。

实现通过管道使父子进程通信

打印结果:

匿名管道读写特征(四种)

1.读快,写慢

写入慢,读取快,read调用阻塞,即进程暂停执行,一直等到有数据来到为止

2.读慢,写快

写入快,读取慢,write调用阻塞,直到有进程读走数据

3.写入端关闭,读取端未关闭

管道写端对应的文件描述符被关闭,则read返回0

当写入端关闭了,读取端就没有等待的必要了,读取端的read()直接返回0,表示写入端关闭了。

4.读取端关闭,写入端未关闭

管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE让write进程退出

匿名管道实现简易进程池

processPool.cc文件

task.hpp文件

运行结果:

命名管道

理论

使用范围:命名管道可以实现任何进程之间的通信。
命名管道实现的过程:

第一步:创建命名管道

使用指令:mkfifo 文件名   创建命名管道

创建命名管道之后,该如何让不同的进程看到同一份资源呢?

首先,我们需要将这个命名管道做唯一标识。

其次,让不同的文件都通过这个唯一标识,就能确定双方找到的文件是同一份文件了。

就好像钥匙和锁一样。现在有很多钥匙,A进程手里10把要是,B进程手里10把钥匙,现在A和B进程都找自己的钥匙,只要能打开同一把锁,就是相同的钥匙。

如何做到唯一标识?

之前在文件系统中说到,为什么同一个目录下的文件不能重名?就是因为目录下存的是文件的文件名,目录通过文件名找文件,所以,不能重名。

这里同理,利用同一路径 + 文件名的方式唯一标识文件

第二步:进程之间使用命名管道通信

通信过程和匿名管道一样。

第三步:删除命名管道(如果不在程序中删除,就要自己手动删除)

使用指令:unlink 文件名

实践

创建命名管道

参数:

第一个参数是pathname,表示要创建的管道文件所在的路径文件名

第二个参数是权限,一般设置0666或者0664

作用:

创建一个命名管道

返回值:

如果创建成功,则返回0,否则返回-1

使用:

进程之间使用命名管道通信

实现命名管道通信,需要两个进程,我们姑且将两个进程命名为客户端(client)和服务端(sliver),客户端发信息,服务端接受信息。

客户端写入

服务端读取

服务端程序

只读端,打开管道文件的方式是O_RDONLY。

接下来就是文件描述符fd中读取sizeof(buffer)个字节内容到buffer中。为了方便观察,将buffer中的内容打印到显示器上。

客户端程序

写入端打开文件的时候使用O_WRONLY

之后将内容输入到line中,将line中的内容写入到fd中,拱读取端去读

实现进程间通信完整程序

实现日志

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

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

相关文章

openharmony launcher 调研笔记(01)数据初始化

最近在看launcher,把自己调研的点做个笔记,持续修改更新中,个人笔记酌情参考。 初始化MainAbility ● common 等 包以 三方库形式 被引入使用 在每个包中的oh-package.json5 文件有配置 { "devDependencies": {}, "n…

docker 部署 Epusdt - 独角数卡 dujiaoka 的 usdt 支付插件

部署 部署说明 部署之前必须注意的几点事项,该教程不一定适合所有用户: 本教程主要是使用 docker 部署,宝塔用户或宿主机直接安装的用户请直接参考官网教程.本教程是独立部署 epusdt,使用独立的mysql和redis,与dujiaoka项目分开. 在研究的过程中发现 epusdt 也需要用到 mys…

SpringCloud Alibaba Sentinel 规则持久化

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅,从传统的模块之间调用,一步步的升级为 SpringCloud 模块之间的调用,此篇文章为第十七篇,即使用 Sentinel 实现规则持久化。 二、概述 从前面我们做的实验可知,…

SpringCloud Alibaba Sentinel 创建流控规则

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅,从传统的模块之间调用,一步步的升级为 SpringCloud 模块之间的调用,此篇文章为第十四篇,即介绍 SpringCloud Alibaba Sentinel 创建流控规则。 二、基本介绍 我们在 senti…

uniapp vue2 时钟 循环定时器

效果展示: 时钟 写在前面:vue2有this指向,没有箭头函数 实验操作:封装一个时钟组件 uniapp vue2 封装一个时钟组件 核心代码: this指向的错误代码,在下: start() { this.myTimer setInterval(…

ctfshow web入门 文件包含 web151--web161

web151 打算用bp改文件形式(可能没操作好)我重新试了一下抓不到 文件上传不成功 改网页前端 鼠标右键&#xff08;检查&#xff09;&#xff0c;把png改为php访问&#xff0c;执行命令 我上传的马是<?php eval($_POST[a]);?> 查看 web152 上传马 把Content-Type改为…

js 数组 按列循环二维数组

期待效果&#xff1a; 核心代码&#xff1a; //js function handle(array) {var result [];for (let i 0; i < array[0].length; i) {var item []; for (let j 0; j < array.length; j) {item.push(array[j][i])} result.push(item);} return result; } 运行代码&a…

全面解析十七种数据分析方法,具象数据分析思维

一、介绍 在当今数据驱动的商业环境中&#xff0c;数据分析已经成为了企业获取竞争优势的关键工具。无论是为了优化运营效率&#xff0c;提高客户满意度&#xff0c;还是推动产品创新&#xff0c;企业都需要通过分析大量数据来做出明智的决策。数据分析方法多种多样&#xff0c…

Android详细介绍POI进行Word操作(小白可进)

poi-tl是一个基于Apache POI的Word模板引擎&#xff0c;也是一个免费开源的Java类库&#xff0c;你可以非常方便的加入到你的项目中&#xff0c;并且拥有着让人喜悦的特性。 一、使用poi前准备 1.导入依赖&#xff1a; 亲手测过下面Android导入POI依赖的方法可用 放入这个 …

3D桌面端可视化引擎HOOPS Visualize如何实现3D应用快速开发?

HOOPS Visualize是一个开发平台&#xff0c;可实现高性能、跨平台3D工程应用程序的快速开发。一些主要功能包括&#xff1a; 高性能、以工程为中心的可视化&#xff0c;使用高度优化的OpenGL或DirectX驱动程序来充分利用可用的图形硬件线程安全的C和C#接口&#xff0c;内部利用…

回顾闰年问题——基础

复习一下闰年问题&#xff1a; 定义&#xff1a;闰年是为了调整日历年与回归年之间的差异而设立的。由于地球绕太阳运行的周期是365天5小时48分46秒&#xff08;即365.24219天&#xff09;&#xff0c;而我们通常使用的公历年只有365天&#xff0c;所以每四年会累积大约一天的差…

深入理解GO语言——GC垃圾回收二

文章目录 前言一、Go V1.5的三色并发标记法总结 前言 书接上回&#xff0c;无论怎么优化&#xff0c;Go V1.3都面临这个一个重要问题&#xff0c;就是mark-and-sweep 算法会暂停整个程序 。 Go是如何面对并这个问题的呢&#xff1f;接下来G V1.5版本 就用 三色并发标记法 来优…