当前位置: 首页 > news >正文

命名管道原理(和匿名管道的对比),mkfifo(命令行,函数),命名管道模拟实现代码+与多个子进程通信代码

目录

命名管道

引入

原理

和匿名管道的对比

使用 -- mkfifo

命令行指令

 创建

文件类型p

使用

函数

函数原型

模拟实现

头文件

客户端代码

服务端代码

运行情况

模拟实现 -- 与多个子进程

介绍

服务端代码: 

运行情况


命名管道

引入

匿名管道只能用于父子进程之间通信,如果我们想要两个完全无关联的进程通信该怎么办?

  • 首先,通信本质还是不变的 : 要让不同的进程看到同一份资源
  • 依然还是用文件作为中间介质,但拿到文件的方式不同

原理

  • 如果一个进程打开一个文件,另一个进程也想打开这个文件:
  • 直接让该进程也指向这个已存在的file结构体(不需要再创建一个file,否则内存中会存在大量相同的数据)

  • 但是!普通文件的数据是要被刷新到磁盘上的
  • 我们的目的可不是为了将数据写到磁盘,而是让两个进程进行通信
  • 因此需要尽量避免io(1是 io速度太慢,2是 通信过程产生的数据没必要写到磁盘上)
  • 因此,管道文件油然而生(也就是命名管道),它是一种特殊的文件
  • 它一旦被打开,就会有自己的路径(路径具有唯一性)
  • 因此,不同进程就可以通过唯一的路径来访问同一个管道文件

和匿名管道的对比

两种管道本质上都是一样的(都是文件) 

实现[让不同进程看到同一份资源]的手段不同

  • 匿名管道 -- 子进程继承父进程的文件描述符表,[直接用fd拿到文件]
  • 命名管道 -- 两个进程访问同一路径下的文件,[用路径拿到文件]

使用 -- mkfifo

命令行指令

 创建

文件类型p

p(pipe) -- 管道文件

使用

当只有一个进程打开该管道时,会阻塞

两个不同进程打开同一路径的管道文件(一个命令就是一个进程 ,echo和cat)

就可以进行通信噜

函数

函数原型

模拟实现

头文件

comm.hpp:

#ifndef COMM_H
#define COMM_H#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <string>
#include <fcntl.h>
#include<unistd.h>using namespace std;string pipe_path = "./fifo.ipc";
#define mode 0666
#define num 1024#endif

log.hpp:

#pragma once#include <iostream>
#include <string>
#include<time.h>using namespace std;#define debug 0
#define notice 1
#define warning 2
#define error 3const string msg[]  //定义不同类型的信息状态
{"debug", "notice", "warning", "error"
};ostream& log(string message,int level) { cout<<"|"<<(unsigned)time(nullptr)<<"|"<<message<<"|"<<msg[level]<<"|"<<endl;return cout;
}

客户端代码

#include"comm.hpp"//用于发送信息(客户端)
int main(){//文件操作int fd=open(pipe_path.c_str(),O_WRONLY|O_TRUNC);if(fd<0){perror("open");exit(1);}string buffer;while(true){cout<<"Please enter the information you want to send : "<<endl;getline(cin,buffer);  //输入要发送的信息int size=write(fd,buffer.c_str(),buffer.size());//向管道文件写入if(size<0){perror("write");exit(2);}else if(size==0){break;}} exit(fd);return 0;
}

服务端代码

#include "comm.hpp"
#include"log.hpp"// 用于接收信息(服务端)int main()
{// 创建管道文件if (mkfifo(pipe_path.c_str(), mode) < 0){perror("mkfifo");}log("创建管道文件成功",debug);// 文件操作int fd = open(pipe_path.c_str(), O_RDONLY);if (fd < 0){perror("open");exit(1);}log("打开文件成功",debug);// 进行通信char buffer[num];while (true){memset(buffer, 0, sizeof buffer);ssize_t size = read(fd, buffer, sizeof buffer - 1);//读取管道文件中的内容cout<<size<<endl;if (size < 0){perror("read");exit(2);}else if (size == 0){cerr << "read end , client quit , sever quit too " << endl;break;}else{cout << "send_message is : " << buffer << endl;log("读取信息成功",debug);}}// 关闭close(fd);log("关闭管道文件成功",debug);unlink(pipe_path.c_str());log("删除管道文件成功",debug);return 0;
}

运行情况

创建管道,等待另一方打开该管道

一端打开文件后,另一端才打开

服务端收到客户端发送的信息

客户端关闭,服务端也退出当服务端关闭,客户端也会退出

 

模拟实现 -- 与多个子进程

介绍

  • 其他部分与上面相同,只需要在服务端修改
  • 将读取信息的部分分装一个函数
  • 然后在服务端创建子进程,让子进程去读取客户端发送的信息

服务端代码: 

#include "comm.hpp"
#include"log.hpp"// 用于接收信息(服务端)void recive_message(int fd){char buffer[num];while (true){memset(buffer, 0, sizeof buffer);ssize_t size = read(fd, buffer, sizeof buffer - 1);//cout<<size<<endl;if (size < 0){perror("read");exit(2);}else if (size == 0){cerr <<"[ " << getpid() << " ]" << "read end , client quit , sever quit too " << endl;break;}else{cout << "[ " << getpid() << " ]" <<" send_message is : " << buffer << endl;log("读取信息成功",debug);}}
}
int main()
{// 创建管道文件if (mkfifo(pipe_path.c_str(), mode) < 0){perror("mkfifo");}log("创建管道文件成功",debug);// 文件操作int fd = open(pipe_path.c_str(), O_RDONLY);if (fd < 0){perror("open");exit(1);}log("打开文件成功",debug);for(int i=0;i<process_size;i++){size_t id=fork();if(id==0){recive_message(fd); //创建子进程去读取exit(0);}}for(int i=0;i<process_size;i++){pid_t ret=waitpid(-1,nullptr,0);}// 关闭close(fd);log("关闭管道文件成功",debug);unlink(pipe_path.c_str());log("删除管道文件成功",debug);return 0;
}

运行情况

相关文章:

命名管道原理(和匿名管道的对比),mkfifo(命令行,函数),命名管道模拟实现代码+与多个子进程通信代码

目录 命名管道 引入 原理 和匿名管道的对比 使用 -- mkfifo 命令行指令 创建 文件类型p 使用 函数 函数原型 模拟实现 头文件 客户端代码 服务端代码 运行情况 模拟实现 -- 与多个子进程 介绍 服务端代码: 运行情况 命名管道 引入 匿名管道只能用于父子进程…...

pytest全局变量的使用

这里重新阐述下PageObject设计模式&#xff1a; PageObject设计模式是selenium自动化最成熟&#xff0c;最受欢迎的一种模式&#xff0c;这里用pytest同样适用 这里直接提供代码&#xff1a; 全局变量 conftest.py """ conftest.py 全局变量&#xff0c;主要实…...

FreeRTOS源码阅读笔记2--list.c

list.c中主要完成列表数据结构的操作&#xff0c;有列表和列表项的初始化、列表的插入和移除。 2.1列表初始化vListInitialise() 2.1.1函数原型 void vListInitialise( List_t * const pxList ) pxList&#xff1a;列表指针&#xff0c;指向要初始化的列表。 2.1.2函数框架…...

杂货铺 | citespace的使用

安装教程 【CiteSpace保姆级教程1】文献综述怎么写&#xff1f; &#x1f4da;数据下载 1. 新建文件夹 2. 数据下载 知网高级检索 数据选中导出 &#xff1a;一次500 导出后重命名为download_xxx.txt&#xff0c;放到input文件里 3. 数据转换 把output里的数据复制到data里…...

C++ 静态成员变量初始化规则

每一天一个小trick&#xff01;&#xff01; 为什么静态成员不能在类内初始化&#xff1f; 在C中&#xff0c;类的静态成员&#xff08;static member&#xff09;必须在类内声明&#xff0c;在类外初始化&#xff0c;像下面这样。 class A { private: static int count …...

Docker安装、卸载,以及各种操作

docker是一个软件&#xff0c;是一个运行与linux和windows上的软件&#xff0c;用于创建、管理和编排容器&#xff1b;docker平台就是一个软件集装箱化平台&#xff0c;是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中&#xf…...

深入理解 C 语言的内存管理

文章目录 引言内存管理的重要性C语言内存布局C语言内存管理堆和栈内存的区别和用途内存分配和释放的过程C语言动态内存分配的概念和原因malloc()、calloc() 和 realloc() 等函数的使用悬挂指针和野指针内存泄漏和如何避免结论 引言 C语言是充满力量且灵活的编程语言&#xff0…...

利用Caddy实现http反向代理

利用Caddy实现http反向代理 1 Caddy是什么 Caddy是一个开源的&#xff0c;使用Golang编写的&#xff0c;支持HTTP/2的Web服务端。它的一个显著特征就是默认启用HTTPS。 和nginx类似。 2 多个后端服务 假如现在有3个后端http服务&#xff1a;分别在启动在 app1 http://10…...

【Qt之QVariant】使用

介绍 QVariant类类似于最常见的Qt数据类型的联合。由于C禁止联合类型包括具有非默认构造函数或析构函数的类型&#xff0c;大多数有趣的Qt类不能在联合中使用。如果没有QVariant&#xff0c;则QObject::property()和数据库操作等将会受到影响。 QVariant对象同时持有一个单一…...

xv6实验课程--xv6的写时复制fork(2023)

7. xv6实验课程--xv6的写时拷贝(COW)(2021) 7. xv6实验课程--xv6懒惰分页分配&#xff08;lazy)(2020) 本文来源&#xff1a; https://mp.weixin.qq.com/s/XJkhjrlP232ZDsRyXd0oHQ 已完成的实验代码可以从下列网站获取&#xff1a; git clone https://gitee.com/lhwhit196…...

在Windows或Mac上安装并运行LLAMA2

LLAMA2在不同系统上运行的结果 LLAMA2 在windows 上运行的结果 LLAMA2 在Mac上运行的结果 安装Llama2的不同方法 方法一&#xff1a; 编译 llama.cpp 克隆 llama.cpp git clone https://github.com/ggerganov/llama.cpp.git 通过conda 创建或者venv. 下面是通过conda 创建…...

Spring底层原理学习笔记--第七讲--(初始化与销毁)

初始化与销毁 Spring提供了多种初始化和销毁手段它们的执行顺序 A07Application.java package com.lucifer.itheima.a07;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springfram…...

基于斑马算法的无人机航迹规划-附代码

基于斑马算法的无人机航迹规划 文章目录 基于斑马算法的无人机航迹规划1.斑马搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用斑马算法来优化无人机航迹规划。 1.斑马搜索算法 …...

干货 | 接口自动化测试分层设计与实践总结

接口测试三要素&#xff1a; 参数构造 发起请求&#xff0c;获取响应 校验结果 一、原始状态 当我们的用例没有进行分层设计的时候&#xff0c;只能算是一个“苗条式”的脚本。以一个后台创建商品活动的场景为例&#xff0c;大概流程是这样的(默认已经是登录状态下)&#…...

【Linux】服务器与磁盘补充知识,硬raid操作指南

服务器硬件 cpu 主板 内存 硬盘 网卡 电源 raid卡 风扇 远程管理卡 1.硬盘尺寸: 目前生产环境中主流的两种类型硬盘 3.5寸 和2.5寸硬盘 2.5寸硬盘可以通过使用硬盘托架后适用于3.5寸硬盘的服务器 但是3.5寸没法转换成2.5寸 2.如何在服务器上制作raid 华为服务器为例子做…...

【java】实现自定义注解校验——方法二

自定义注解校验的实现步骤&#xff1a; 1.创建注解类&#xff0c;编写校验注解&#xff0c;即类似NotEmpty注解 2.编写自定义校验的逻辑实体类&#xff0c;编写具体的校验逻辑。(这个类可以实现ConstraintValidator这个接口&#xff0c;让注解用来校验) 3.开启使用自定义注解进…...

算法通关村第六关|白银|二叉树的层次遍历【持续更新】

1.二叉树基本的层序遍历 仅仅遍历并输出全部元素。 List<Integer> simpleLevelOrder(TreeNode root) {if (root null) {return new ArrayList<Integer>();}List<Integer> res new ArrayList<Integer>();LinkedList<TreeNode> queue new Lin…...

vue中通过js控制scss变量

<!--* Description:* Author: 李大玄* Date: 2022-07-28 20:34:43* FilePath: /web-framework-demo/src/views/layout.vue* LastEditors: 李大玄* LastEditTime: 2022-11-01 09:25:31 --> <template><div height"100%" class"b"><inp…...

深度学习理论知识入门【EM算法、VAE算法、GAN算法】和【RBM算法、MCMC算法、HMC算法】

目录 深度学习理论知识入门首先&#xff0c;让我们了解第一个流程&#xff1a;现在&#xff0c;让我们看看第二个流程&#xff1a; EM算法GMM&#xff08;高斯混合模型&#xff09; 深度学习理论知识入门 首先&#xff0c;让我们了解第一个流程&#xff1a; EM&#xff08;Exp…...

Java8实战-总结47

Java8实战-总结47 CompletableFuture&#xff1a;组合式异步编程让代码免受阻塞之苦使用定制的执行器 对多个异步任务进行流水线操作 CompletableFuture&#xff1a;组合式异步编程 让代码免受阻塞之苦 使用定制的执行器 就这个主题而言&#xff0c;明智的选择似乎是创建一个…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

沙箱虚拟化技术虚拟机容器之间的关系详解

问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西&#xff0c;但是如果把三者放在一起&#xff0c;它们之间到底什么关系&#xff1f;又有什么联系呢&#xff1f;我不是很明白&#xff01;&#xff01;&#xff01; 就比如说&#xff1a; 沙箱&#…...