Linux:命名管道及其实现原理
文章目录
- 命名管道
- 指令级命名管道
- 代码级命名管道
本篇要引入的内容是命名管道
命名管道
前面的总结中已经搞定了匿名管道,但是匿名管道有一个很严重的问题,它只允许具有血缘关系的进程进行通信,那如果是两个不相关的进程进行通信,此时应该如何处理?此时就可以采用的是命名管道
从名字上能看出来,它既然叫命名管道,就说明它是有名字的
指令级命名管道
系统默认是支持指令级别的命名管道的,例如在bash中的竖划线实际上就是指令级别的匿名管道,而命名管道当然也是有指令级别的
fifo指令
从指令的角度来讲,使用fifo命令就可以创建出一条命名管道,例如使用mkfifo filename,就可以在当前目录下创建出一个命名管道:
从上述的指令中可以看到,确确实实一个命名管道被创建出来了,并且在权限前面的p也证明这是一个管道文件
为什么说它是一个命名管道?第一个是说它有文件名,其实还有一层原因是因为它存在路径,只要有路径和文件名,未来就可以通过路径和文件名找到这个文件,既然可以找到文件,就可以借助这个文件进行进程间的通信,那么下面来看如何进行进程间的通信
上述是最简单的管道通信示意图,基本原理就是一个进程把内容放入到管道中,另外一个进程从管道中读取信息,这就是最基本的原理
这个管道和匿名管道的一个区别是,匿名管道是内存级的文件,简单来说就是不会在磁盘上创建信息,操作系统关闭这个文件也就随之消失了,而命名管道是一个磁盘级的文件,不会随着操作系统的关闭而消失,所以可以把这个文件当做是一个正常的文件来看待
那么和正常文件的其中一个区别是,向管道中输入文件后会发现,此时文件的大小依旧是0:
出现这样的原因是,虽然它是一个磁盘级的文件,但是在实际的数据通信的过程,这个文件必然是要读端和写端分别对两个程序进行开放,那么既然这个文件已经被打开了,那么它的数据就没有必要向磁盘中刷新,所以磁盘中这个文件此时还是没有数据的,而对于其他的文件,都会及时的向磁盘中做刷新,以保存到磁盘中
管道的原理
下面讨论的内容是关于管道文件的原理,现在有两个进程a和进程b,通信的本质是让两个进程看到同一份资源,这样就可以借助这个同一份资源实现进程之间的通信了,这是在最初就创建出的观点,那么对于命名管道来说,如何能让两个资源都看到我呢?怎么能保证呢?其实借助的就是路径名和文件名的唯一性,这样从宏观上来讲就能保证看到的是同一份资源,换个角度,从微观上讲,看到的真的是同一份资源吗?答案也是肯定的,下面给出具体的解释
首先,文件是存在于磁盘中的,现在a进程有它对应的PCB,有自己的文件描述符表,b进程也有自己的PCB和文件描述符表,而现在如果a进程打开了这个路径中名字为某个名字的命名管道文件,操作系统为了方便管理信息,就要为这个文件创建一个文件结构体来管理这个文件对象,然后再将文件描述符分配给a进程的文件描述符表当中,同时也有文件对应的文件缓冲区,如果这是一个普通文件,那么未来就可以借助这个文件缓冲区将内容刷新到磁盘中或者是把磁盘中的内容读取到内存中,这些都是可以理解的,那么下一个要探讨的问题是,如果此时还有一个进程b把这个文件打开了,那么操作系统是否还会做出同样的内容呢?会不会继续加载这个文件对应的文件缓冲区,然后再创建等等一系列步骤呢?答案显然是不会的,因为操作系统是一个非常讲究效率的模块,它不会做出任何违背效率的事,所以文件的内容都存储在内存中,属性也已经加载好了,那么操作系统就不会重新加载了,所以两个进程打开了同一个文件,文件对应的缓冲区,内容和属性这些内容都是不用再重新加载的,但是还会有对应的文件结构体,用来描述这个文件进行读写到什么位置,这些还是会对应的进行加载的
用下图来对上述的这一系列原理做出一个解释:
从这个图也能看出来,其实命名管道和匿名管道的原理基本上是一样的,没什么区别,操作系统判别到底是不是一个文件的标准就是看路径+文件名,有了文件名就有了inode,于是就有了这上述的一系列逻辑,就做到了,让进程a和进程b都看到了同一份资源,进而借助缓冲区完成了进程之间的通信
代码级命名管道
其实相比起匿名管道来说,命名管道反而更加简单,所以有了前面进程池的代码基础,实现也不算很难:
// comm.h
#pragma once#define FILENAME "fifo"
// client.cc
#include <iostream>
#include <cstring>
#include <cerrno>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "comm.h"int main()
{int wfd = open(FILENAME, O_WRONLY);if (wfd < 0){std::cerr << "errno: " << errno << ", errstring: " << strerror(errno) << std::endl;return 1;}std::cout << "open fifo success... write" << std::endl;std::string message;while (true){std::cout << "Please Enter# ";std::getline(std::cin, message);ssize_t s = write(wfd, message.c_str(), message.size());if (s < 0){std::cerr << "errno: " << errno << ", errstring: " << strerror(errno) << std::endl;break;}}close(wfd);std::cout << "close fifo success..." << std::endl;return 0;
}
// server.cc
#include <iostream>
#include <cstring>
#include <cerrno>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "comm.h"bool MakeFifo()
{int n = mkfifo(FILENAME, 0666);if (n < 0){std::cerr << "errno: " << errno << ", errstring: " << strerror(errno) << std::endl;return false;}std::cout << "mkfifo success... read" << std::endl;return true;
}int main()
{
Start:int rfd = open(FILENAME, O_RDONLY);if (rfd < 0){std::cerr << "errno: " << errno << ", errstring: " << strerror(errno) << std::endl;if (MakeFifo())goto Start;elsereturn 1;}std::cout << "open fifo success..." << std::endl;char buffer[1024];while (true){ssize_t s = read(rfd, buffer, sizeof(buffer) - 1);if (s > 0){buffer[s] = 0;std::cout << "Client say# " << buffer << std::endl;}else if (s == 0){std::cout << "client quit, server quit too!" << std::endl;break;}}close(rfd);std::cout << "close fifo success..." << std::endl;return 0;
}
相关文章:

Linux:命名管道及其实现原理
文章目录 命名管道指令级命名管道代码级命名管道 本篇要引入的内容是命名管道 命名管道 前面的总结中已经搞定了匿名管道,但是匿名管道有一个很严重的问题,它只允许具有血缘关系的进程进行通信,那如果是两个不相关的进程进行通信࿰…...
实习记录——第五天
今天我的心情不是很美丽,昨天晚上没怎么睡好,因为我一直在想离不离开实验室?该怎么说的事情?但是又觉得这个项目还没有完全结束,冒昧提这个事情是不是不好?最终也没得出一个结论,晚上睡得也不踏…...

Kotlin 教程(环境搭建)
Kotlin IntelliJ IDEA环境搭建 IntelliJ IDEA 免费的社区版下载地址:Download IntelliJ IDEA – The Leading Java and Kotlin IDE 下载安装后,我们就可以使用该工具来创建项目,创建过程需要选择 SDK, Kotlin 与 JDK 1.6 一起使…...

04.领域驱动设计:了解聚合和聚合根,怎样设计聚合-学习总结
目录 1、概述 2、聚合 3、聚合根 4、怎么设计聚合 4.1 聚合的构建过程主要步骤 第 1 步:采用事件风暴。 第 2 步:选出聚合根。 第 3 步:找出与聚合根关联的所有紧密依赖的实体和值对象。 第 4 步:画出对象的引用和依赖模型…...

cmake-find_package链接第三方库
文章目录 基本调用形式和模块模式使用方式 之前我们是使用了绝对路径来链接OpenCV第三方库,但是现在很多库一般会自己写一些cmake文件提供给用户,用户可以直接使用其中的内置变量即可。使用的命令就是find_package。 基本调用形式和模块模式 find_packa…...

obsidian阅读pdf和文献——与zotero连用
参考: 【基于Obsidian的pdf阅读、标注,构建笔记思维导图,实现笔记标签化、碎片化,便于检索和跳转】 工作流:如何在Obsidian中阅读PDF - Eleven的文章 - 知乎 https://zhuanlan.zhihu.com/p/409627700 操作步骤 基于O…...

走方格(动态规划)
解题思路: 找边界,即行为1,列为1。 拆分问题,拆分成一次走一步,只能向右或者向下走。 解题代码: public static void main(String[] args) {int [][]arrnew int[31][31];Scanner scnew Scanner(Sys…...

基于DataKit迁移MySQL到openGauss
📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…...

API网关-Apinto压缩包方式自动化安装配置教程
文章目录 前言一、Apinto安装教程1. 复制脚本2. 增加执行权限3. 执行脚本4. Apinto命令4.1 启动Apinto4.2 停止Apinto4.3 重启Apinto4.4 查看Apinto版本信息4.5 加入Apinto集群4.6 离开Apinto集群4.7 查看Apinto节点信息 5. 卸载Apinto 二、Apserver(Apinto Dashboard V3)安装教…...

内网穿透natapp使用教程(Linux)
我的使用场景:在家访问学校服务器,由于不在一个局域网,所以需要使用内网穿透,我使用的是natapp。需要在有局域网的时候做好以下步骤。 (natapp官网:https://natapp.cn/) 1. 下载客户端 &#x…...
php函数 二
一 字符串包含 1.1 str_starts_with(string $haystack, string $needle) php8版本中新函数。 检查字符串是否以指定子串开头,区分大小写。返回布尔值。 $haystack待判断的字符串,$needle需要查询的内容。 function test1() {$str "Qwe asd zx…...

IDC机房交换机核心技术与应用指南
IDC机房交换机核心技术与应用指南 在这个快速发展的数字时代,数据中心作为信息技术的心脏,不仅承载着海量数据的处理、存储和传输,更是支撑着全球企业运营和互联网服务的关键基础设施。在众多构成数据中心的组件中,IDC机房交换…...
Compose | UI组件(五) | Button 按钮组件
文章目录 前言Button 是什么?Button的创建Button显示水平方向的UI IconButton是什么?IconButton是创建 FloatingActionButton是什么?FloatingActionButton创建 ExtendedFloatingActionButton是什么? 总结 前言 随着移动端的技术不…...
【leetcode刷刷】235. 二叉搜索树的最近公共祖先 、701.二叉搜索树中的插入操作 、450.删除二叉搜索树中的节点
235. 二叉搜索树的最近公共祖先 class Solution:def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:# 递归if not root: return if root.val p.val: return pif root.val q.val: return qleft Noneright Noneif root.val > p.…...

YoloV8改进策略:BackBone改进|DCNv4最新实践|高效涨点|多种改进教程|完整论文翻译
摘要 涨点效果:在我自己的数据集上,mAP50 由0.986涨到了0.993,mAP50-95由0.737涨到0.77,涨点明显! DCNv4是可变形卷积的第四版,速度和v3相比有了大幅度的提升,但是环境搭建有一定的难度,对新手不太友好。如果在使用过程遇到编译的问题,请严格按照我写的环境配置。 …...

高中数学常识
一、大小关系 |x| > |sinx| 理由: 很明显,在圆内,弧长x>垂线sinx 3x、2x 、 1 2 \frac{1}{2} 21x 理由: log 1 2 _\frac{1}{2} 21x、log 2 _2 2x、 log 3 _3 3x 二、(xy)? 的求法 利用二项式定理 三、平…...

docker之部署青龙面板
青龙面板是一个用于管理和监控 Linux 服务器的工具,具有定时运行脚本任务的功能。在实际情况下也可以用于一些定期自动签到等任务脚本的运行。 本次记录下简单的安装与使用,请提前安装好docker,参考之前的文章。 一、安装部署 1、拉取镜像 # …...

Type-C平板接口协议芯片介绍,实现单C口充放电功能
在现代平板电脑中,Type-C接口已经成为了一个非常常见的接口类型。相比于传统的USB接口,Type-C接口具有更小的体积、更快的传输速度和更方便的插拔体验。但是,在使用Type-C接口的平板电脑上,如何实现单C口充电、放电和USB2.0数据传…...

系统架构演变
1.1系统架构的演变 2008年以后,国内互联网行业飞速发展,我们对软件系统的需求已经不再是过去”能用就行”这种很low的档次了,像抢红包、双十一这样的活动不断逼迫我们去突破软件系统的性能上限,传统的IT企业”能用就行”的开发思…...
Oracle PL/SQL Programming 第2章:Creating and Running PL/SQL Code 读书笔记
总的目录和进度,请参见开始读 Oracle PL/SQL Programming 第6版 暂不考虑系统设计或单元测试之类的任务,所有 PL/SQL 程序员必须熟悉的基本操作任务包括: 浏览数据库创建和编辑 PL/SQL 源代码编译 PL/SQL 源代码,并更正编译器注…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...