当前位置: 首页 > 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;明智的选择似乎是创建一个…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域&#xff0c;无损检测&#xff08;NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统&#xff0c;以非接触式光学麦克风技术为核心&#xff0c;打破传统检测瓶颈&#xff0c;为半导体、航空航天、汽车制造等行业提供了高灵敏…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

密码学基础——SM4算法

博客主页&#xff1a;christine-rr-CSDN博客 ​​​​专栏主页&#xff1a;密码学 &#x1f4cc; 【今日更新】&#x1f4cc; 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 ​编辑…...

边缘计算网关提升水产养殖尾水处理的远程运维效率

一、项目背景 随着水产养殖行业的快速发展&#xff0c;养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下&#xff0c;而且难以实现精准监控和管理。为了提升尾水处理的效果和效率&#xff0c;同时降低人力成本&#xff0c;某大型水产养殖企业决定…...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题&#xff0c;进而引发后续程序异常。使用工具进行标准化操作&#xff0c;能有效降低出错概率。 需要快速整理大量文件的技术用户而言&#xff0c;这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB&#xff0c;…...