【Linux】进程间通信——命名管道

文章目录
- 命名管道
- 什么是命名管道
- **命名管道 vs. 无名管道**
- 如何创建命名管道
- 用命名管道实现进程间通信
- Makefile
- Comm.hpp
- Server.hpp
- Client.hpp
- Server.cpp
- Client.cpp
- 效果
- 总结
命名管道
什么是命名管道
命名管道,也称为 FIFO(First In First Out),是一种 进程间通信(IPC) 机制,它允许不相关的进程(即没有父子关系的进程)通过文件系统中的特殊文件进行数据传输。
命名管道 vs. 无名管道
| 类型 | 说明 | 适用场景 |
|---|---|---|
| 匿名管道 | pipe() 创建,仅限于父子进程之间通信 | 适用于父进程创建子进程并通信 |
| 命名管道 | mkfifo() 创建,存在于文件系统中,可用于任意进程间通信 | 适用于独立进程间通信 |
如何创建命名管道

手动创建命名管道:
mkfifo FIFO

这个FIFO也是一个文件,被操作系统特殊标记过,是管道文件。
在C语言库中有一个函数也是mkfifo,这个接口解决了进程间通信的问题。

用命名管道实现进程间通信

我们创建一下文件,Client是模拟的客户端用于发送请求,server是服务端,用于接收请求,Comm用于存储全局变量,还有一些都要用到的函数,Makefile用来编译可执行程序,首先我们将Makefile完善。
Makefile
SERVER=server
CLIENT=client
cc=g++
SERVER_SRC=Server.cc
CLIENT_SRC=Client.cc.PHONY:all
all:$(SERVER) $(CLIENT)$(SERVER):$(SERVER_SRC)$(cc) -o $@ $^ -std=c++11
$(CLIENT):$(CLIENT_SRC)$(cc) -o $@ $^ -std=c++11.PHONY:clean
clean:rm -f $(SERVER) $(CLIENT)
由于在Makefile中只能创建一个可执行文件,所以我们需要加上这一段:
这一段表示all,这个伪目标依赖下面两个可执行程序,所以不得不创建下面两个可执行程序来完成这个伪目标了。
Comm.hpp
#pragma once#include <iostream>
#include <string>
#include <unistd.h>
#include <thread>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
using namespace std;//双方通信使用的文件
const string gpipefile = "./fifo";
const mode_t gmode = 0600;//允许拥有者写,所属组和other什么权限都没有
const int gdefulted = -1;
const int gsize = 1024;
const int gForRead = O_RDONLY;
const int gForWrite = O_WRONLY;//打开管道
int OpenPipe(int flag)
{//以只读方式打开int fd = open(gpipefile.c_str(),flag);if(fd < 0){cerr<<"open error"<<endl;return false;}return fd;
}
void ClosePipeHelper(int fd)
{if(fd >= 0) close(fd);
}
由于客户端和服务器都要打开管道和关闭管道,所以我们将这两个接口放在Comm中,但是因为这两个端的打开方式不一样,所以我们用一个参数来代替,调用这个函数的时候只需要传递调用的方式就行了。
Server.hpp
#pragma once
#include "Comm.hpp"class Init
{
public://创建文件Init(){umask(0);//先将缺省权限清零int n = mkfifo(gpipefile.c_str(),gmode);if(n < 0)//创建管道文件失败{cerr<<"mkfifo error"<<endl;return;}cout<<"mkfifo success"<<endl;}//销毁文件~Init(){//删除当前路径下的文件int n = unlink(gpipefile.c_str());//判断是否删除成功if(n < 0){cerr<<"unlink error"<<endl;return;}cout<<"unlink success"<<endl;}
};Init init;class Server
{
public://初始化Server():_fd(gdefulted){}bool OpenPipeForRead(){_fd = OpenPipe(gForRead);if(_fd < 0)return false;return true;}//读取管道//string *out:输出型参数//const string &输入型参数//string &输入输出型参数 int RecvPipe(string *out){char buffer[gsize];//读取文件ssize_t n = read(_fd,buffer,sizeof(buffer)-1);//预留一个空间,后面是期望读这么多,n是实际读取的字节数if(n > 0)//读取成功{buffer[n]=0;//读取成功将buffer带出去*out = buffer;}//返回read实际的字节数return n;}void ClosePipe(){ClosePipeHelper(_fd);}~Server(){}
private:int _fd;
};
首先是创建管道文件,我们封装一个类,用于管理管道文件的创建和销毁,声明一个全局变量,构造函数用于创建管道,析构函数用于销毁管道,由于全局变量的生命周期是和程序一样的,所以当程序结束的时候管道文件也跟着销毁,也意味着通信结束。
Server是客户端用于接收请求,意思是我们要将Client发送的信息输出到屏幕上。

这个函数就是用于读取管道内部客户端发送的请求。
Client.hpp
#pragma once
#include "Comm.hpp"//看到同一份资源class Client
{
public://初始化Client():_fd(gdefulted){}//打开管道bool OpenpipeForWrite(){_fd = OpenPipe(gForWrite);if(_fd < 0) return false;return true;}//发送管道int SendPipe(const string& in){return write(_fd,in.c_str(),sizeof(in));}//关闭管道void ClosePipe(){ClosePipeHelper(_fd);}~Client(){}
private:int _fd;
};
Client唯一和Server不一样的就是一个是读取,一个是发送,而Client就是发送,向服务器发送信息。

所以这里直接向管道中写即可。
string *out:输出型参数 | const string &输入型参数 | string &输入输出型参数
上面是每个参数的意义
Server.cpp
#include "Server.hpp"int main()
{Server server;server.OpenPipeForRead();string message;while(true){if(server.RecvPipe(&message) > 0){cout<<"client Say#"<<message<<endl;}else break;}cout<<"client quit,me too"<<endl;server.ClosePipe();return 0;
}
Client.cpp
#include "Client.hpp"int main()
{Client client;client.OpenpipeForWrite();string message;while(true){cout<<"please Enter#";getline(cin,message);client.SendPipe(message);//这里的message从标准输入来}client.ClosePipe();return 0;
}
效果

当客户端关闭时服务器也会跟着关闭

总结
命名管道(FIFO)作为 Linux 进程间通信(IPC)的一种机制,提供了一种基于文件系统的数据传输方式,使得不相关进程之间也能进行数据交换。相比于无名管道,它具有更高的灵活性,不需要父子进程关系,适用于生产者-消费者模式、日志收集、进程调试等场景。
通过 mkfifo 创建命名管道,我们可以实现进程间的数据流动,而不必使用共享内存或消息队列等复杂机制。命名管道不仅支持流式数据传输,还能够跨终端、跨进程进行数据交互,极大简化了进程间通信的实现。
总结来说,命名管道是一种简单、高效、灵活的 IPC 机制,适用于轻量级的数据传输需求,在系统编程和日常应用中都有着广泛的应用。
通过实践,我们也看到了命名管道的易用性与强大功能,它使得开发者能够更加高效地实现进程间的数据交换,促进了软件系统的模块化与解耦。
相关文章:
【Linux】进程间通信——命名管道
文章目录 命名管道什么是命名管道**命名管道 vs. 无名管道**如何创建命名管道 用命名管道实现进程间通信MakefileComm.hppServer.hppClient.hppServer.cppClient.cpp 效果总结 命名管道 什么是命名管道 命名管道,也称为 FIFO(First In First Out&#…...
Qt在Linux嵌入式开发过程中复杂界面滑动时卡顿掉帧问题分析及解决方案
Qt在Linux嵌入式设备开发过程中,由于配置较低,加上没有GPU,我们有时候会遇到有些组件比较多的复杂界面,在滑动时会出现掉帧或卡顿的问题。要讲明白这个问题还得从CPU和GPU的分工说起。 一、硬件层面核心问题根源剖析 CPU&#x…...
AI学习第六天-python的基础使用-趣味图形
在 Python 编程学习过程中,turtle库是一个非常有趣且实用的工具,它可以帮助我们轻松绘制各种图形。结合for循环、random模块以及自定义方法等知识点,能够创作出丰富多彩的图案。下面就来分享一下相关的学习笔记。 一、基础知识点回顾 &…...
[VMware]卸载VMware虚拟机和Linux系统ubuntu(自记录版)
记录一下,不是教程,只是防止我做错了可以回溯一下 我打开vscode,就会跳出下图 虚拟机,Linux还是很久之前学习安装的,种途可能卸载过(不太记得了),现在尝试彻底卸载 彻底卸载VMware虚拟机的详细步骤-CSDN博客虚拟机Vmware 转移 克隆 卸载及移除Linux系统_克隆的虚拟机怎么移除-…...
J-LangChain,用Java实现LangChain编排!轻松加载PDF、切分文档、向量化存储,再到智能问答
Java如何玩转大模型编排、RAG、Agent??? 在自然语言处理(NLP)的浪潮中,LangChain作为一种强大的模型编排框架,已经在Python社区中广受欢迎。然而,对于Java开发者来说,能…...
Cuppa CMS v1.0 任意文件读取(CVE-2022-25401)
漏洞简介: Cuppa CMS v1.0 administrator/templates/default/html/windows/right.php文件存在任意文件读取漏洞 漏洞环境: 春秋云镜中的漏洞靶标,CVE编号为CVE-2022-25401 漏洞复现 弱口令行不通 直接访问administrator/templates/defau…...
可以免费无限次下载PPT的网站
前言 最近发现了一个超实用的网站,想分享给大家。 在学习和工作的过程中,想必做PPT是一件让大家都很头疼的一件事。 想下载一些PPT模板减少做PPT的工作量,但网上大多精美的PPT都是需要付费才能下载使用。 即使免费也有次数限制࿰…...
STM32中使用PWM对舵机控制
目录 1、硬件JIE 2、PWM口配置 3、角度转换 4、main函数中应用 5、工程下载连接 1、硬件介绍 单片机:STM32F1 舵机:MG995 2、PWM口配置 20毫秒的PWM脉冲占空比,对舵机控制效果较好 计算的公式: PSC、ARR值的选取…...
使用插件 `vue2-water-marker`添加全局水印
使用插件 vue2-water-marker添加全局水印 效果图 1、安装插件 npm install vue2-water-marker --save2、全局注册 // main.js import Vue from vue import Vue2WaterMarker from vue2-water-markerVue.use(Vue2WaterMarker)3、在组件中使用 <template><div id&q…...
MySQL表约束的种类与应用
在MySQL数据库中,表约束是确保数据完整性的关键。约束限制了可以在表中插入或更新的数据类型,保证数据的准确性和可靠性。了解MySQL中的各种表约束对于数据库设计和数据维护至关重要。以下是MySQL支持的主要表约束类型及其应用的详细介绍。 1. 主键约束…...
【大模型+知识图谱】大模型与知识图谱融合:技术演进、实践应用与未来挑战
【大模型+知识图谱】大模型与知识图谱融合:技术演进、实践应用与未来挑战 大模型与知识图谱融合:技术演进、实践应用与未来挑战引言:为什么需要融合?一、技术融合的三重路径1.1 知识图谱增强大模型1.2 大模型赋能知识图谱1.3 协同推理框架二、工业级应用场景落地2.1 智能问…...
MS SQL 2008 技术内幕:T-SQL 语言基础
《MS SQL 2008 技术内幕:T-SQL 语言基础》是一部全面介绍 Microsoft SQL Server 2008 中 T-SQL(Transact-SQL)语言的书籍。T-SQL 是 SQL Server 的扩展版本,增加了编程功能和数据库管理功能,使得开发者和数据库管理员能…...
MySQL-MATCH ... AGAINST工具
在MySQL中,MATCH……AGAINST是全文索引(Full-Text index)的查询语法,它允许你对文本进行高效的全文搜素,支持自然语言搜索和布尔搜索模式。以下是MATCH……AGAINST的详细用法和示例 一、全文索引的基本概念 全文索引适…...
微服务合并
有的团队为了节约机器成本、有的团队为了提升研发效率、有的团队为了降低人均服务数 微服务合并,可以从多个角度入手 代码重构融合:人工拷贝代码、解决冲突,然后分阶段实施迁移重构。代码合并打包:将多个代码仓库,拉取…...
Shell脚本基础:用Bash自动化任务
Shell脚本基础:用Bash自动化任务 在Linux运维中,手动执行重复性任务既耗时又容易出错,而Shell脚本则为自动化提供了强大支持。 从基础概念到实用案例,逐步掌握用Bash实现自动化的核心技能。Shell脚本是Linux自动化的基石…...
基于W2605C语音识别合成芯片的智能语音交互闹钟方案-AI对话享受智能生活
随着科技的飞速发展,智能家居产品正逐步渗透到我们的日常生活中,其中智能闹钟作为时间管理的得力助手,也在不断进化。基于W2605C语音识别与语音合成芯片的智能语音交互闹钟,凭借其强大的联网能力、自动校时功能、实时天气获取、以…...
【Java项目】基于Spring Boot的网上商城购物系统
【Java项目】基于Spring Boot的网上商城购物系统 技术简介:采用Java技术、Spring Boot框架、MySQL数据库等实现。 系统简介:系统实现管理员:首页、个人中心、用户管理、商品分类管理、商品信息管理、订单评价管理、系统管理、订单管理&#x…...
开放标准(RFC 7519):JSON Web Token (JWT)
开放标准:JSON Web Token 前言基本使用整合Shiro登录自定义JWT认证过滤器配置Config自定义凭证匹配规则接口验证权限控制禁用session缓存的使用登录退出单用户登录Token刷新双Token方案单Token方案 前言 JSON Web Token (JWT) 是一种开放标准…...
JBoltAI_SpringBoot如何基于Deepseek官网API区分 R1大模型深度思考和具体回答的内容?
R1大模型推出后,Deepseek官网的API也更新了,我们可以看到 chat 接口的响应数据结果里多了一个reasoning_content 字段 于是我们的JBoltAI SDK 以及 SpringBoot版以及Jfinal版JBoltAI Platform 迅速跟进,提供了对深度思考的支持:…...
YOLOv11-ultralytics-8.3.67部分代码阅读笔记-model.py
model.py ultralytics\models\yolo\model.py 目录 model.py 1.所需的库和模块 2.class YOLO(Model): 3.class YOLOWorld(Model): 1.所需的库和模块 # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/licensefrom pathlib import Pathfrom ult…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案
一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...
