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;
}

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

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

相关文章

《佛法修学概要》009-012集研讨

课程摘要 9、只有走出心中的妄想&#xff0c;才可能接觸彌陀的光明&#xff01; 佛陀在經典裡講出一個譬喻&#xff0c;說有一座動物園&#xff0c;這座動物園關了很多動物。其中有一隻袋鼠&#xff0c;就是澳洲那種很會跳的袋鼠。動物園的管理員&#xff0c;給牠圈了一個十公尺…

《合成孔径雷达成像算法与实现》Figure5.16

clc clear close all距离向参数 R_eta_c 20e3; % 景中心斜距 Tr 25e-6; % 发射脉冲时宽 Kr 0.25e12; % 距离向调频率 Fr 7.5e6; % 距离向采样率 Nrg 256; % 距离线采样点数 Bw abs(Kr*Tr); …

【vue oidc-client】invalid_requestRequest Id: 0HN0OOPFRLSF2:00000002

需求&#xff1a;完成统一登录&#xff0c;需要从三方平台跳到我们的平台。 oidc-client报错记录。这个一般是配置信息出错&#xff0c;需要和三方平台进行沟通&#xff0c;一定要把client_id&#xff0c;密钥进行对应&#xff1b; 同时关于此次出错还修改了以下代码&#xff…

主成分分析(PCA)Python

实际问题研究中&#xff0c;常常遇到多变量问题&#xff0c;变量越多&#xff0c;问题往往越复杂&#xff0c;且各个变量之间往往有联系。于是&#xff0c;我们想到能不能用较少的新变量代替原本较多的旧变量&#xff0c;且使这些较少的新变量尽可能多地保留原来变量所反映的信…

按配置数据绘制配置型地图marker的icon,自定义marker

一、需求 需要自定义配置数据的marker&#xff0c;其中图片内容要灵活可配置自动生成。此处项目用的百度地图。 效果图&#xff1a; 二、思路 用背景图canvas绘制数字的方式生成icon的图片资源。 再将icon生成对应地图marker。 三、代码 canvasImg.js <!-- * descrip…

进程地址空间(Linux)

进程地址空间 一、引入概念1. 程序的地址分布2. 线性地址和物理地址 二、进程地址空间1. 初步认识2. 地址空间和物理内存的联系3. 区域划分4. 拓展——关于“线” 三、进一步理解进程地址空间四、页表总结 一、引入概念 1. 程序的地址分布 测试代码&#xff1a; #include &l…

Nginx安装以及具体应用

文章目录 Centos7安装NginxNginx命令Nginx具体应用反向代理 location指令说明负载均衡动静分离 Nginx.conf配置详解 Centos7安装Nginx 下载地址&#xff1a;nginx: download 中间这个就是tar.gz包 Centos7安装Nginx 下载nginx-1.16.1.tar.gz上传到Centos7中的/user/local目…

java8 流到底是什么呢?

引入背景&#xff1a; 1、想像写SQL那样操作集合 2、为了提高性能&#xff0c;需要并行处理&#xff0c;并利用多核架构 流到底是什么呢&#xff1f; 流是Java API的新成员&#xff0c;它允许你 以声明性方式处理数据集合&#xff08;通过查询语句来表达&#xff0c;而不是临时…

springboot+vue3组合,对接支付宝付款第一节:内网穿透

springbootvue3组合,对接支付宝付款第一节:内网穿透&#xff01;接下来会为大家展示&#xff0c;使用java的springboot搭建一个简单的后台。提供业务接口。实现在线下单&#xff0c;支付。支付宝付款的案例。 前端页面布局我们使用vue3element-plus来实现绘制。 今天是第一个…

海康实时监控预览视频流接入web

我们采取的方案是后端获取视频流返回给前端&#xff0c;然后前端播放 海康开放平台海康威视合作生态致力打造一个能力开放体系、两个生态圈&#xff0c;Hikvision AI Cloud开放平台是能力开放体系的核心内容。它是海康威视基于多年在视频及物联网核心技术积累之上&#xff0c;…

Jmeter连接数据库报错Cannot load JDBC driver class‘com.mysql.jdbc.Driver’解决

问题产生: 我在用jmeter连接数据库查询我的接口是否添加数据成功时,结果树响应Cannot load JDBC driver class com.mysql.jdbc.Driver 产生原因: 1、连接数据库的用户密码等信息使用的变量我放在了下面,导致没有取到用户名密码IP等信息,导致连接失败 2、jmeter没有JDB…

CodeGPT--(Visual )

GitCode - 开发者的代码家园 gitcode.com/ inscode.csdn.net/liujiaping/java_1706242128563/edit?openFileMain.java&editTypelite marketplace.visualstudio.com/items?itemNameCSDN.csdn-codegpt&spm1018.2226.3001.9836&extra%5Butm_source%5Dvip_chatgpt_c…

Elasticsearch介绍以及基本操作

目录 一、Elasticsearch介绍 二、关于Elasticsearch的基本操作 &#xff08;1&#xff09;索引操作 &#xff08;2&#xff09;文档操作 三、域的属性 &#xff08;1&#xff09;index &#xff08;2&#xff09;type &#xff08;3&#xff09;store 一、Elasticsearc…

使用Go语言编写安全的HTTP代理服务器

构建一个安全的HTTP代理服务器是至关重要的&#xff0c;因为这可以保护用户的数据和隐私。让我们来看看如何使用Go语言编写一个安全的HTTP代理服务器。 首先&#xff0c;确保你的代理服务器使用HTTPS协议进行通信。HTTPS使用SSL/TLS加密来保护数据传输&#xff0c;可以确保数据…

源聚达科技:抖店的专营店怎么开

在数字化浪潮的推动下&#xff0c;抖音平台不仅为人们提供了丰富的娱乐内容&#xff0c;也成为了电商的新战场。不少创业者和品牌商纷纷选择在抖音上开设自己的专营店&#xff0c;以此抓住流量红利&#xff0c;拓宽销售渠道。那么&#xff0c;如何在抖音平台上成功开设一家专营…

每日一题——LeetCode1346.检查整数及其两倍数是否存在

方法一 循环查找 用indexOf查找每个元素的两倍是否存在在数组中&#xff0c;找到了就直接return true&#xff0c;循环结束还没找到就return false var checkIfExist function(arr) {for(let i0;i<arr.length;i){let index arr.indexOf(arr[i]*2)if(index>0 &&…

听力下降为什么会影响到言语感知?

一、听力障碍对阈值、听觉频率范围和分辨能力的影响 听力障碍使得听障者的听敏度降低&#xff0c;提高了阈值&#xff0c;不利于言语信号的接收。听障者听力阈值的变化在不同频率并不相同&#xff0c;一般而言&#xff0c;高频部分的听力损失往往大于低频部分&#xff0c;而言…

fatal error:require():Failed opening required

今天部署网站遇到了个错误 fatal error:require():Failed opening required 这个错误经常遇到 大多是网站 是开启了 open_basedir 但今天这个错误很神奇 先说解决方法 1. 检测一下是不是真的 不存在这个文件 即使100%确定 也建议你再仔细看一下 这个文件存不存在 今天我遇…

Linux:利用匿名管道构建进程池

文章目录 进程池实现进程池创建信道和进程发送任务释放资源 进程池代码总结 本篇的主题是借助前面所学的基础管道实现一个进程池&#xff0c;那么在实现进程池前先了解进程池是什么&#xff0c;进程池有什么意义&#xff0c;进而对于进程池有一个基本的把握 进程池 给定一个进…

学习笔记-李沐动手学深度学习(四)(12-13,权重衰退、L2正则化、Dropout)

总结 【trick】过拟合及正则化项参数的理解 实际数据都有噪音&#xff0c;一般有噪音后&#xff0c;模型实际学习到的权重w就会比 理论上w的最优解&#xff08;即没有噪音时&#xff09;大。&#xff08;QA中讲的&#xff09; 【好问题】 &#xff08;1&#xff09;不使用正…