【Linux】命名管道
一、命名管道的原理
在前面的博客中,我们学习了匿名管道,了解到了两个具有血缘关系的进程之间是如何进行通信的?那么在没有血缘关系(毫不相关)的进程之间是如何进行通信的?
大致思路是一样的,我们还是需要能够进行让两个进程之间可以看到同一份资源,然后在同一份资源中进行读写和通信。如何让两个进程看见同一份文件呢??由于在Linux系统中,Linux的树形结构保证了一个文件只有一个唯一的路径。我们可以根据文件的路径来找到同一份文件。

二、使用指令来看一下命名管道
在man手册中,可以查到指令的命名管道:

mkfifo XXXX

我们可以进行通信,复制一下终端,利用两个终端进行通信:在一个终端中利用echo来打印到屏幕中,用另一个终端进行接收显示。
// 循环打印到命名管道的命令为:
while :; do echo "Hello world" ; sleep 1; done > myfifo// 接收的命令为:
cat < myfifo
在一个过程中有两个细节:
1. 在向命名管道中写入时,管道中的容量大小怎么进行改变?
为什么会有上面的现象呢??
命名管道和匿名管道一样,都是内存文件,只不过命名管道在磁盘有一个简单的映像,但这个映像的大小永远为0,因为命名管道和匿名管道都不会将通信数据刷新到磁盘当中。
2. 我在接收端将读端进行关闭,为什么进程会直接退出呢?
在之前的匿名管道的博客中,我们知道:读端直接关闭,写端一直在写,写端进程会被操作系统直接使用13号信号进行关闭,相当于程序出现异常。因为echo是内建命令,是有bash进程进行控制的。当我们终止掉读端进程后,因为写端执行的循环脚本是由命令行解释器bash执行的,所以此时bash就会被操作系统杀掉,我们的云服务器也就退出了。
三、命名管道的代码
现在,我们使用代码来创建一个命名管道,具体代码如下:
3.1 先来介绍一下使用的函数
3.1.1 mkfifo函数
函数的原型:
函数的参数部分:
- pathname:创建管道文件的文件路径
- mode:存放创建管道文件的权限
函数的返回值:
- 如果函数成功返回0,如果失败返回-1
函数的功能:
- 该函数用于在文件系统中创建一个文件,该文件用于提供FIFO功能,即命名管道。
3.1.2 unlink函数
函数的原型:
函数的参数部分:
- pathname:创建管道文件的文件路径
函数的返回值:
- 函数的返回值为 0 表示成功,-1 表示失败,并设置相应的错误码。
函数的功能:
- 该函数用于删除文件系统中的文件。它通过删除文件系统中文件的链接,从而使文件系统中不再存在该文件的链接。
- 当所有链接(包括硬链接和符号链接)都被删除之后,文件系统便会回收文件占用的磁盘空间。
- 需要注意的是,删除文件并不会立即释放文件的磁盘空间,而是在文件的引用计数为零时才会真正回收空间。
3.1.3 open函数
函数的原型:
函数的参数:
- pathname:创建管道文件的文件路径
- flags:一些标志位,我们需要认识一些标志位,这些标志位通过按位与进行传参,我们需要通过位图的知识点来将每一个标志位进行分开,分别进行不同函数的操作。open函数的一些标志位的写法和用途:
函数的返回值:
- 调用成功时返回一个文件描述符fd,调用失败时返回-1,并修改errno
函数的功能:
- 打开文件
3.1.4 write函数

3.1.5 read函数

3.2 命名管道类的编写
3.2.1 创建命名管道的代码编写
const std::string comepath = "./myfifo"; // 先确定要打开的文件路径int CreateNamePipe(const std::string &path)
{int res = mkfifo(path.c_str(), 0666); // 在相应的路径创建管道文件,并设置其权限if (res != 0){perror("mkfifo");std::cerr << "errno:" << errno << std::endl;}return res;
}
3.2.2 删除管道文件的代码编写
int RemoveNamePipr(const std::string &path)
{int res = unlink(path.c_str());if (res != 0){perror("RemoveNamePipe");}return res;
}
3.2.3 最后将两个函数进行整合
class NamePipe
{
public:// 创建管道NamePipe(const std::string &path, int who): fifo_pipe(path), _id(who), _fd(default){if (_id == Creater){int res = mkfifo(path.c_str(), 0666);if (res != 0){perror("mkfifo");}std::cout << "Craeter create name pipe" << std::endl;}}// 销毁管道~NamePipe(){if (_id == Creater){int res = unlink(fifo_pipe.c_str());if (res != 0){perror("RemoveNamePipe");}std::cout << "Create free name pipe" << std::endl;}if(_fd != default) close(_fd);}private:const std::string &fifo_pipe; // 存放管道文件的路径int _id; // 检查是创建者还是使用者int _fd; // 存放文件描述符
};
3.3 打开管道文件的代码编写
我们已经知道了文件的路径,这时,我们需要调用open函数来进行文件的打开,并且表示是以读的形式打开,还是以写的形式打开。利用系统调用函数,将管道文件打开。
bool opennamepipe(int mode)
{_fd = open(fifo_pipe.c_str(), mode); // mode传递的是标志位if (_fd < 0){return false;}return true; // _fd是文件描述符
}
3.4 以读的形式或者以写的形式打开文件的代码编写
在打开文件的open函数中有一个标志位,我们可以使用标志位对文件进行不同的操作。
#define Read O_RDONLY // 标志位
#define Write O_WRONLY// 以读的形式打开
bool openforread()
{return opennamepipe(Read);
}// 以写的形式打开
bool operforwrite()
{return opennamepipe(Write);
}
3.5 读管道和写管道
// 读管道
int ReadNamePipe(std::string *out)
{char buff[Basesize];int n = read(_fd, buff, sizeof buff);if(n > 0){buff[n] = '\0';*out = buff;}return n;
}// 写管道
int WriteNamePipe(const std::string& in)
{return write(_fd, in.c_str(), in.size());
}
3.6 编写发送端和接收端的代码编写
读端的代码:
#include "namedpipe.hpp"// server进行读取,管理命名管道的整个生命周期
int main()
{// 创建管道NamePipe fifo(comepath, Creater);// 对于读端而言,如果我们打开文件,但是写端还没来,我会阻塞在open调用中,直到对方打开// 进程同步,if (fifo.openforread()){while (true){std::string message;int n = fifo.ReadNamePipe(&message);if (n > 0){std::cout << "Client sat:" << message << std::endl;}else if(n == 0){std::cout << "Client quit, server too" << std::endl;break;}else{std::cout << "fifo.ReadNamePipe error" << std::endl;break;}}}return 0;
}
写端的代码:
#include "namedpipe.hpp"int main()
{NamePipe fifo(comepath, User);if (fifo.operforwrite()){while (true){std::cout << "Plass Enter:" << std::endl;std::string message;std::getline(std::cin, message);fifo.WriteNamePipe(message);}}return 0;
}
有一个细节
3.7 对代码进行进一步的修改
使得代码中管道的释放可以顺序进行。
四、回归概念
最后,我们在来复盘一下匿名管道和命名管道。让不同的进程看到同一份资源,匿名管道和命名管道的区别是:匿名管道是父子间继承的方式来进行看到同一份管道资源,而命名管道是通过文件的唯一路径来看到同一份管道资源。
相关文章:
【Linux】命名管道
一、命名管道的原理 在前面的博客中,我们学习了匿名管道,了解到了两个具有血缘关系的进程之间是如何进行通信的?那么在没有血缘关系(毫不相关)的进程之间是如何进行通信的? 大致思路是一样的,我…...
IMX6Q基于linux4.1.15调试音频芯片tas2505
IMX6Q基于linux4.1.15调试音频芯片tas2505 1、开发环境2、初步想法3、开发过程4、tas2505重要的寄存器5、遇到的问题1、开发环境 芯片:IMX6Q (NXP系列) 内核版本:linux4.1.15 Ubuntu版本:16.04 目标模块:tas2505 2、初步想法 由于该电路是由外部晶振提供的时钟频率24.5…...
卷积常用网络
目录 1.AlexNet2.VGG3.GoogleNet4.ResNet5.MobileNet 1.AlexNet AlexNet是2012年ISLVRC 2012(ImageNet Large Scale Visual Recognition Challenge)竞赛的冠军网络。 首次利用 GPU 进行网络加速训练。使用了 ReLU 激活函数,而不是传统的 Si…...
Firebase Local Emulator Suite详解
文章目录 Firebase Local Emulator Suite 组件安装和使用步骤1. 安装 Firebase CLI2. 初始化 Firebase 项目3. 配置模拟器4. 启动模拟器5. 配置应用程序使用本地模拟器 常见用途 Firebase Local Emulator Suite 是一组本地服务,可以模拟 Firebase 平台的在线服务&am…...
计算机组成原理·存储系统疑点归纳
组原这门课有点学得不是很懂,现在快考试了,挑几个做错了的题分析、记录一下。 N o . 1 \mathit{No}.1 No.1 x x x、 y y y 为定点整数,其格式为 1 1 1 位符号位、 n n n 位数值位,若采用补码一位乘法实现乘法运算,则…...
在 GPU 上实现全规模文件系统加速
摘要 现代高性能计算和人工智能计算解决方案经常使用 GPU 作为其主要计算能力来源。这就为 GPU 应用程序的存储操作造成了严重的不平衡,因为每一个此类存储操作都必须向 CPU 发出信号并由 CPU 处理。在 GPU4FS 中,我们针对这种不平衡提出了一个彻底的解决…...
代码随想录算法训练营Day7|454.四数相加II、 383. 赎金信、15. 三数之和、 18. 四数之和
454.四数相加II 四个数组分成两组进行for循环,先用HashMap存储所有第一组for循环出现的和的次数。再进行第二组for循环,每一次得出的和判断其负数是否在map的key中,如果存在,就加上这个value。 class Solution {public int four…...
编译器屏障概述
文章目录 1. 前言2. 编译器内存屏障2.1 编译器内存访问重排序规则2.2 编译器屏障的几种形式2.2.1 显式编译器屏障2.2.2 隐式编译器屏障2.2.3 硬件内存屏障充当编译屏障2.2.4 编程语言内存模型提供的编译屏障 2.3 编译器内存屏障实例2.3.1 Linux spinlock 3. 结语4. 参考资料 1.…...
RUST宏编程入门
宏指示符 在Rust的宏编程中,宏可以接受多种类型的参数,称为“指示符”。这些指示符帮助宏识别不同类型的代码片段,并相应地处理它们。 这里列出全部指示符: blockexpr 用于表达式ident 用于变量名或函数名itemliteral 用于字面常…...
linux安装srs
获取srs cd /opt git clone -b 4.0release https://gitee.com/ossrs/srs.git cd srs/trunk 启动srs ./objs/srs -c conf/srs.conf ./etc/init.d/srs status 访问http://192.168.220.146:8080/出现下方图片说明安装成功 点击进入SRS控制台看到下方图片...
IO流(2)
缓冲流 字节缓冲流 利用字节缓冲区拷贝文件,一次读取一个字节: public class test {public static void main(String [] args) throws IOException {//利用字节缓冲区来拷贝文件BufferedInputStream bisnew BufferedInputStream(new FileInputStream(&…...
【docker】docker启动bitnami/mysql
说明:-v 宿主机目录:docker容器目录,-p 同理 注意:/opt/bitnami/mysql/conf/bitnami 目录自定义conf的目录,不能使用原有的/opt/bitnami/mysql/conf 目录。 容器启动后可在宿主机的/宿主/mysql8.0/conf,添加my_custom.…...
边缘计算、云计算、雾计算在物联网中的作用
边缘计算和雾计算不像云那样广为人知,但可以为企业和物联网公司提供很多帮助。这些网络解决了物联网云计算服务无法解决的许多问题,并使分散的数据存储适应特定的需求。让我们分别研究一下边缘计算、雾计算和云计算的优势。 雾计算的好处 低延迟。雾网络…...
【c语言】探索内存函数
探索内存函数 memcpy函数memmove函数memset函数memcmp函数: memcpy函数 memcpy函数声明: void * memcpy ( void * destination, const void * source, size_t num );将source空间下的num个字符复制到dest中去 函数的使用: 将字符数组a的5字…...
day46 完全背包理论基础 518. 零钱兑换 II 377. 组合总和 Ⅳ
完全背包理论基础 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。 01背包内嵌的循环是从…...
【linux】运维-基础知识-认知hahoop周边
1. HDFS HDFS(Hadoop Distributed File System)–Hadoop分布式文件存储系统 源自于Google的GFS论文,HDFS是GFS的克隆版 HDFS是Hadoop中数据存储和管理的基础 他是一个高容错的系统,能够自动解决硬件故障,eg:…...
Python自动实时查询预约网站的剩余名额并在有余额时发邮件提示
本文介绍基于Python语言,自动、定时监测某体检预约网站中指定日期的体检余额,并在有体检余额时自动给自己发送邮件提醒的方法。 来到春招末期,很多单位进入了体检流程。其中,银行(尤其是四大行)喜欢“海检”…...
Flutter 验证码输入框
前言: 验证码输入框很常见:处理不好 bug也会比较多 想实现方法很多,这里列举一种完美方式,完美兼容 软键盘粘贴方式 效果如下: 之前使用 uniapp 的方式实现过一次 两种方式(原理相同)࿱…...
如何从0到设计一个CRM系统
什么是CRM 设计开始之前,先来了解一下什么是CRM。CRM(Customer Relationship Management)是指通过建立和维护与客户的良好关系,达到满足客户需求、提高客户满意度、增加业务收入的一种管理方法和策略。CRM涉及到跟踪和管理客户的所…...
Numba 的 CUDA 示例 (2/4):穿针引线
本教程为 Numba CUDA 示例 第 2 部分。 按照本系列从头开始使用 Python 学习 CUDA 编程 介绍 在本系列的第一部分中,我们讨论了如何使用 GPU 运行高度并行算法。高度并行任务是指任务完全相互独立的任务,例如对两个数组求和或应用任何元素函数。 在本教…...
中国跨境电商大会代理授权机制与决策影响分析
对于众多寻求通过“中国跨境电商大会”精准撬动海外市场的企业而言,面对琳琅满目的代理商选择,决策过程本身就是一次关于市场洞察、风险评估与资源匹配的深度考验。一个优质的代理商,不仅是展位的“售票员”,更是企业出海战略的“…...
深入解析Shim在跨版本API兼容中的实战应用
1. 什么是Shim技术 第一次听到"Shim"这个词是在调试一个Flink连接Hive的项目时。当时Hive版本从2.3升级到3.1,本以为要重写大量代码,结果同事说"加个Shim就行了"。这种"神奇胶水"般的技术让我印象深刻。 Shim本质上是一种…...
如何通过FCEUX实现NES游戏高精度模拟?解锁经典游戏的数字化体验
如何通过FCEUX实现NES游戏高精度模拟?解锁经典游戏的数字化体验 【免费下载链接】fceux FCEUX, a NES Emulator 项目地址: https://gitcode.com/gh_mirrors/fc/fceux 你是否曾因找不到可靠的NES模拟器而无法重温童年经典游戏?是否遇到过模拟器兼容…...
OpCore-Simplify:让黑苹果配置从复杂到简单的智能化革命
OpCore-Simplify:让黑苹果配置从复杂到简单的智能化革命 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 你是否曾为黑苹果(Hac…...
MySQL登录报错1045?手把手教你找回丢失的root用户(附完整修复流程)
MySQL登录报错1045:从root用户丢失到完整恢复的实战指南 当你信心满满地输入mysql -u root -p准备开始一天的工作,却迎面撞上冰冷的"ERROR 1045 (28000): Access denied for user rootlocalhost"时,这种挫败感每个DBA都深有体会。更…...
腾讯云+Astrbot个人AI部署,接入QQ机器人
1、腾讯云创建云服务器 之所以选择腾讯云是因为可以领一个月免费服务器 地址:https://cloud.tencent.com/ 服务器配置情况: 这里我获取的是轻量应用服务器(Lighthouse),适合网站搭建、开发测试等多种场景。以下是详细…...
PEI转染试剂及相关工具在生命科学研究中的应用解析【曼博生物官方代理Polysciences】
摘要:聚乙烯亚胺(PEI)转染试剂在基因递送、病毒载体生产等领域应用广泛。本文结合Polysciences相关产品体系,对PEI转染、微球技术及神经示踪染料等工具进行系统梳理。 关键词:PEI转染、聚乙烯亚胺、基因转染、HEK293、…...
OpenClaw成本优化方案:ollama GLM-4.7-Flash自建模型接口实践
OpenClaw成本优化方案:ollama GLM-4.7-Flash自建模型接口实践 1. 为什么需要关注OpenClaw的token消耗问题 第一次用OpenClaw完成自动化周报任务时,我盯着账单倒吸一口凉气——生成三份周报竟然消耗了接近15万token。这让我意识到,如果不解决…...
大语言模型训练中的显存占用与优化方法简述
在进行大语言模型(LLM)的微调或预训练时,显存(VRAM)不足通常是首要面临的问题。为了在有限的硬件资源下完成训练,了解显存的具体去向以及相应的优化技术是比较基础的工作。 从模型训练的流程来看ÿ…...
十大经典排序算法解析与实现
## 1. 十大经典排序算法技术解析### 1.1 算法分类体系 排序算法可分为两大技术类别:**比较类排序**: - 通过元素间比较确定相对次序 - 时间复杂度下限为O(nlogn) - 典型代表:快速排序、堆排序、归并排序**非比较类排序**: - 不依赖…...




函数的参数部分:
