【Linux】第三十二站:命名管道

文章目录

  • 一、命名管道介绍
  • 二、编码
    • 1.mkfifo
    • 2.unlink
    • 3.一个简单的例子
    • 4.修改

一、命名管道介绍

管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。

如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。

命名管道是一种特殊类型的文件

image-20240120181817217

我们可以直接使用下面的命令去创建命名管道

mkfifo myfifo

image-20240120182450551

它的文件类型是以p开头的,也就是命名管道

其实这个myfifo命名管道文件,它在磁盘中并没有数据,它更多的只是一种符号

如下所示

当我们左侧将内容输入到管道的时候,左侧会先进入阻塞。直到右侧使用cat拿到数据以后,左侧才会结束

image-20240120182624167

首先这两个指令是两个进程,这两个进程是毫无关系,但是他们是可以利用这个命名管道进行通信的

也可以看到,在写入的过程中,命名管道的大小一直是0

image-20240120183043910

我们也知道,如果两个不同的进程,打开同一个文件的时候,在内核中,操作系统也是打开一个文件,还是我们前面的这一套

image-20240120210716329

所以:

进程间通信的前提:先让不同的进程看到同一份资源

现在我们的这个管道文件其实就是一个内存级文件,它是不需要刷盘的!

那么我们怎么保证我们两个进程打开的是同一个文件呢?

只要同路径下的同一个文件名即可–>路径 + 文件名具有唯一性

二、编码

1.mkfifo

如下所示

image-20240120212754825

上面的函数可以去创建一个管道文件,第一个参数是路径,第二个是管道的权限是什么,如果成功是0,否则返回-1

如下代码所示

image-20240121123911378

image-20240121123855603

2.unlink

如果我们想要删除一个文件我们可以使用unlink接口

image-20240121124057956

如果成功,返回,如果失败返回-1

如下代码所示

image-20240121124451755

我们可以先编译运行一下,我们会发现会先报错说管道文件已经存在,这是正常的,因为我们之前的并没有删除掉

image-20240121124438918

当我们将原来的管道删除以后,重新运行,就可以看到了

image-20240121125130086

3.一个简单的例子

#pragma once
#include <iostream>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string>
#define FIFO_FILE "./myfifo"
#define MODE 0664enum 
{FIFO_CREATE_ERR = 1,FIFO_DELETE_ERR,FIFO_OPEN_ERR};
using namespace std;
#include "comm.hpp"int main()
{int fd = open(FIFO_FILE,O_WRONLY);if(fd < 0){perror("clinet open file fail...");exit(FIFO_OPEN_ERR);}cout << "client open success" <<endl;string line;while(1){cout << "Please Enter@ ";getline(cin,line);write(fd, line.c_str(), line.size());}close(fd);cout << "客户端关闭啦!..." << endl;return 0;
}
#include "comm.hpp"
using namespace std;int main()
{//创建一个管道int n = mkfifo(FIFO_FILE, MODE);if(n == -1) {perror("mkfifo");exit(FIFO_CREATE_ERR);}//开始通信int fd = open(FIFO_FILE,O_RDONLY);if(fd < 0){perror("open:");exit(FIFO_OPEN_ERR);}cout <<"server open file sueccess" <<endl;while(1){char buffer[1024] = {0}; ssize_t x = read(fd, buffer, sizeof(buffer) - 1);if(x > 0){buffer[x] = 0;cout << "服务器收到客户端发送的消息:"<< buffer <<endl;}else if(x == 0){cout << "客户端关闭,服务器关闭" << endl;break;}else {break;}}close(fd);//关闭信道int m = unlink(FIFO_FILE);if(m == -1){perror("unlink:");exit(FIFO_DELETE_ERR);}return 0;
}

如上代码所示,最终的运行结果为

当我们先打开服务端的时候,我们发现服务端创建了管道,但是并没有打印出server open file success,这说明open处阻塞了

image-20240121153225268

当我们一旦打开了客户端,服务端和客户端几乎同时打开成功。这说明,命名管道文件需要写端和读端都打开的时候才可以,否则只打开其中一个会进入阻塞。我们可以理解为这是为了防止只打开读端,不打开写端的管道会出现读入0的情况。只打开写端,不打开读端会杀掉写端的进程

image-20240121153337884

然后就可以通信了

最终我们我们关闭客户端的同时,由于关闭了写端,但是读端没有关闭,就会读入0,最终服务端的代码逻辑会检测到这个0,从而结束进程

image-20240121153654275

同样的,如果我们先关闭了服务端,那么就会杀掉客户端的进程

image-20240121153931796

4.修改

我们现在对上面的代码进行一下小小的修改,使代码变得更加优雅

如下所示,我们让创建管道和销毁管道变成一个类,这样的话,就不需要我们自己去手动控制了

#pragma once
#include <iostream>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string>
#define FIFO_FILE "./myfifo"
#define MODE 0664enum 
{FIFO_CREATE_ERR = 1,FIFO_DELETE_ERR,FIFO_OPEN_ERR};class Init
{
public:Init(){//创建一个管道int n = mkfifo(FIFO_FILE, MODE);if(n == -1) {perror("mkfifo");exit(FIFO_CREATE_ERR);}}~Init(){//关闭信道int m = unlink(FIFO_FILE);if(m == -1){perror("unlink:");exit(FIFO_DELETE_ERR);}}};

客户端还是不变的

using namespace std;
#include "comm.hpp"int main()
{int fd = open(FIFO_FILE,O_WRONLY);if(fd < 0){perror("clinet open file fail...");exit(FIFO_OPEN_ERR);}cout << "client open success" <<endl;string line;while(1){cout << "Please Enter@ ";getline(cin,line);write(fd, line.c_str(), line.size());}close(fd);cout << "客户端关闭啦!..." << endl;return 0;
}

下面是服务端,就可以通过一个变量的定义来控制前面的创建管道和关闭管道了

#include "comm.hpp"
using namespace std;int main()
{Init in;//开始通信int fd = open(FIFO_FILE,O_RDONLY);if(fd < 0){perror("open:");exit(FIFO_OPEN_ERR);}cout <<"server open file sueccess" <<endl;while(1){char buffer[1024] = {0}; ssize_t x = read(fd, buffer, sizeof(buffer) - 1);if(x > 0){buffer[x] = 0;cout << "服务器收到客户端发送的消息:"<< buffer <<endl;}else if(x == 0){cout << "客户端关闭,服务器关闭" << endl;break;}else {break;}}close(fd);return 0;
}

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

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

相关文章

14 STM32 - IIC (时序图+软件源码)

14.1 IIC简介 IIC&#xff08;Inter-Integrated Circuit&#xff09;&#xff0c;中文集成电路总线&#xff0c;是一种串行通信总线&#xff0c;使用多主从架构。I2C串行总线一般有两根信号线&#xff0c;一根是双向的数据线SDA&#xff0c;另一根是时钟线SCL。所有接到I2C总线…

【蓝桥杯备赛Java组】语言基础|竞赛常用库函数|输入输出|String的使用|常见的数学方法|大小写转换

&#x1f3a5; 个人主页&#xff1a;深鱼~&#x1f525;收录专栏&#xff1a;蓝桥杯&#x1f304;欢迎 &#x1f44d;点赞✍评论⭐收藏 目录 一、编程基础 1.1 Java类的创建 1.2 Java方法 1.3 输入输出 1.4 String的使用 二、竞赛常用库函数 1.常见的数学方法 2.大小写转…

邦芒支招:避免薪资谈崩的六个措施

对于求职者而言&#xff0c;我喜欢把回答薪资问题比喻成玩扑克牌&#xff0c;它的目标就是让招聘方先亮出底牌。其原因在于&#xff0c;正如詹姆斯察觉到的&#xff0c;一旦你暴露了具体的薪资数目&#xff0c;你就会陷入要价太高(或者太低)的境地。 以下这些小技巧也许能为…

函数传参之按值传递

定义&#xff1a;所有函数的参数都是按值传递的&#xff0c;这意味着函数外的值被会被赋值到函数内部的参数中&#xff0c;就像从一个变量赋值到另外一个变量一样 **原始值&#xff1a;那么久跟原始值变量的复制一样** **引用值&#xff1a;那么久跟引用值复制一样**变量有按值…

php基础学习之代码框架

一&#xff0c;标记 脚本标记&#xff08;已弃用&#xff09;&#xff1a;<script language"php"> php代码 </script> 标准标记&#xff1a;<?php php代码 ?> 二&#xff0c;基础输出语句 不是函数&#xff0c;…

国内比较好的sap实施商有哪些?

在当今数字化浪潮的推动下&#xff0c;企业的数字化转型已成为企业竞争力的关键因素。而在众多企业应用软件中&#xff0c;SAP&#xff08;系统应用和产品&#xff09;作为全球的企业资源规划&#xff08;ERP&#xff09;解决方案供应商&#xff0c;扮演着至关重要的角色。然而…

javascript设计模式-应用示例

事件工具类 /* addEvent: simplified event attachment */ function addEvent( obj, type, fn ) {if (obj.addEventListener) {obj.addEventListener( type, fn, false );EventCache.add(obj, type, fn);}else if (obj.attachEvent) {obj["e"typefn] fn;obj[typefn…

【WSL】[出现错误 2147944320 (0x80070780) (启动“ubuntu.exe”时)]

问题描述 在尝试启动 Windows Subsystem for Linux (WSL) 的 “ubuntu.exe” 时&#xff0c;可能会遇到以下错误&#xff1a; [出现错误 2147944320 (0x80070780) (启动“ubuntu.exe”时)]错误的截图如下&#xff1a; 原因分析 系统找不到指定的文件。在这种情况下&#xff…

Git提交 ssh: connect to host github.com port 22: Connection timed out解决方案

你们好&#xff0c;我是金金金。 场景 之前都是好好的&#xff0c;不知道今天为什么提交代码就这样了 排查 根据英文可以看出&#xff0c;ssh端口号被拒绝了&#xff0c;22号端口不行&#xff0c;那就换一个端口 造成error的原因 ssh端口被拒绝 解决 找到.ssh文件&#xff…

CLion调试Nodejs源码

【环境】 macOS node-v20.11.0源码 CLion 2023.3.2 【1】下载源码 https://nodejs.org/en/download/ 【2】编译源码 解压后的目录如下 进入解压后的目录进行编译 ./configure --debug make -C out BUILDTYPEDebug -j 4需要好久… 编译成功之后在node-v20.11.0目录下会有一个…

【Web实操11】定位实操_照片墙(无序摆放)

设置一个板块&#xff0c;将照片随意无序摆放在墙上&#xff0c;从而形成照片墙。本来效果应该是很唯美好看的&#xff0c;就像这种&#xff0c;但是奈何本人手太笨&#xff0c;只好设置能达到照片墙的效果就可。 代码如下&#xff1a; <!DOCTYPE html> <html lang&…

SpringBoot整理-Spring Boot配置

Spring Boot 的配置系统是其核心功能之一,旨在简化 Spring 应用的配置过程。Spring Boot 提供了一种灵活的方式来配置你的应用,无论是通过外部配置文件,环境变量,命令行参数还是在代码中直接配置。以下是关于 Spring Boot 配置的几个重要方面: 配置文件 application.prope…

JavaEE的MVC(Model-View-Controller)设计模式

JavaEE的MVC&#xff08;Model-View-Controller&#xff09;设计模式是一种用于组织和管理Web应用程序的架构模式。MVC模式将应用程序分为三个主要组件&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器&#xff08;Controller&#x…

binary_search_tree的介绍与实现(二叉搜索树精美图示详解哦)

二叉搜搜索树 引言二叉搜索树的介绍二叉搜索树的实现框架默认成员函数构造析构赋值重载 InsertR&#xff08;插入&#xff09;EraseR&#xff08;删除&#xff09;SearchR&#xff08;查找&#xff09; 源码概览总结 引言 在C语言部分&#xff0c;我们已经认识了树与二叉树的结…

【嵌入式经验积累】C语言实现傅里叶变换

文章目录 C 语言实现离散傅利叶变换&#xff08;DFT&#xff09;代码如下&#xff1a;C 语言实现快速傅利叶变换&#xff08;FFT&#xff09;&#xff0c;代码如下&#xff1a;分裂基快速傅利叶变换代码如下。实序列快速傅利叶变换&#xff08;一&#xff09;&#xff0c;代码如…

Nginx 实战指南

Nginx 是一款高性能的开源反向代理服务器,也可用作负载均衡器、Web服务器和缓存服务器。本实战指南将带你深入了解 Nginx 的安装、基础配置、高级配置、最佳实践以及性能调优。 步骤 1: 安装 Nginx Ubuntu sudo apt update sudo apt install nginx CentOS sudo yum insta…

python使用分治算法找出出现次数最多的数字

对于给定的一个长度为n的数组nums&#xff0c;需要找出起重工出现次数大于n/2向下取整的元素&#xff0c;假设给定的数组中一定存在符合给定要求的数&#xff0c;例如给定如下的例子&#xff1a; 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 添加图片注…

docker使用http_proxy配置代理

钢铁知识库&#xff0c;一个学习python爬虫、数据分析的知识库。人生苦短&#xff0c;快用python。 在内网服务器中&#xff0c;docker经常需要下载拉取镜像&#xff0c;但由于没有网络要么只能手动导入镜像包&#xff0c;又或者通过http_proxy代理到其它服务器下载。 解决方法…

看书标记【R语言数据分析项目精解:理论、方法、实战 9】

看书标记——R语言 Chapter 9 文本挖掘——点评数据展示策略9.1项目背景、目标和方案9.1.1项目背景9.1.2项目目标9.1.3项目方案1.建立评论文本质量量化指标2.建立用户相似度模型3.对用户评论进行情感性分析 9.2项目技术理论简介9.2.1评论文本质量量化指标模型1.主题覆盖量2.评论…

FA-分配行重分配报错【APP-OFA-48313】

FA-重分配行报错 已存在行只能分多次转移调整 Ref1&#xff1a; APP-OFA-48313 You Cannot Create Identical Distribution Lines with Transfer (Doc ID 336894.1) APPLIES TO: Oracle Assets - Version 11.5.10.0 and later Information in this document applies to any…