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

🔥个人主页🔥:孤寂大仙V
🌈收录专栏🌈:Linux
🌹往期回顾🌹:【Linux笔记】进程间通信——匿名管道||进程池
🔖流水不争,争的是滔滔不


  • 一、命名管道简介
  • 二、命名管道的一些特性
    • 命名管道的创建
    • 匿名管道与命名管道的区别
    • 命名管道的打开规则
  • 基于命名管道进程间通信的demo代码

一、命名管道简介

命名管道是一种特殊的文件类型,它在文件系统中有一个名字,就像普通文件一样,但它的作用不是存储数据,而是用于进程间通信。与匿名管道不同,命名管道可以在不相关的进程之间进行通信,并且可以跨越不同的主机(在支持网络命名管道的系统中)。

特点

  • 半双工或全双工:命名管道可以配置为半双工或全双工模式。在半双工模式下,数据可以在两个方向上传输,但不能同时进行;在全双工模式下,数据可以同时在两个方向上传输,这使得通信更加灵活,能满足不同应用场景的需求。
  • 面向字节流:命名管道以字节流的形式传输数据,这意味着发送方写入管道的数据会以连续的字节序列被接收方读取,没有固定的消息边界。接收方需要自己根据应用层的协议来解析数据。
  • 同步或异步操作:对命名管道的读写操作可以是同步的,也可以是异步的。同步操作会阻塞进程,直到操作完成;异步操作则允许进程在操作进行的同时继续执行其他任务,提高了程序的并发性能。

工作原理

当一个进程打开命名管道进行写入时,操作系统会为该管道分配一个缓冲区。进程将数据写入缓冲区,然后操作系统负责将数据传递给连接到该管道的读取进程。如果管道缓冲区已满,写入进程可能会被阻塞,直到有空间可用。
读取进程从管道中读取数据时,会从缓冲区中获取数据。如果缓冲区中没有数据,读取进程可能会阻塞,直到有数据可供读取。

优缺点

  • 优点:使用命名管道进行进程间通信相对简单,不需要复杂的网络编程知识。它提供了一种可靠的通信机制,保证数据的顺序性和完整性。此外,命名管道可以在不同的操作系统平台上使用,具有较好的跨平台性。
  • 缺点:命名管道的性能可能不如其他一些高性能的通信机制,如共享内存。在处理大量数据时,可能会存在一定的性能瓶颈。另外,命名管道的通信是基于字节流的,需要应用程序自己处理数据的解析和格式转换,增加了编程的复杂性。

二、命名管道的一些特性

命名管道的创建

命名管道可以从命令行上创建,命令行方法是使用下面这个命令

mkfifo filename

命名管道也可以从程序里创建,相关函数

int mkfifo(const char *filename,mode_t mode);

创建命名管道:

int main(int argc, char *argv[])
{mkfifo("p2", 0644);return 0;
}

匿名管道与命名管道的区别

匿名管道由pipe函数创建并打开。命名管道由mkfifo函数创建,打开用open。FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。

命名管道的打开规则

如果当前打开操作是为读而打开FIFO时

O_NONBLOCK disable:阻塞直到有相应进程为写而打开该FIFO
O_NONBLOCK enable:立刻返回成功

如果当前打开操作是为写而打开FIFO时

O_NONBLOCK disable:阻塞直到有相应进程为读而打开该FIFO
O_NONBLOCK enable:立刻返回失败,错误码为ENXIO

基于命名管道进程间通信的demo代码

通过命名管道,客户端进行写操作,服务端进行读操作

comm.hpp主逻辑的实现

#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
using namespace std;#define PATH "."
#define FILENAME "fifo"class NamedFifo
{
public:NamedFifo(const string& path,const string& name):_path(path),_name(name){_fifoname=_path+"/"+_name;//创建管道umask(0);int n=mkfifo(_fifoname.c_str(),0666);if(n<0){cout<<"管道创建失败"<<endl;}else{cout<<"管道创建成功"<<endl;}}~NamedFifo(){int n=unlink(_fifoname.c_str());if(n<0){cout<<"管道删除失败"<<endl;}else{cout<<"管道删除成功"<<endl;}}
private:string _path;string _name;string _fifoname;
};class FillOper
{
public:FillOper(const string& path,const string& name):_path(path),_name(name),_fd(-1){_fifoname=_path+"/"+_name;}void OpenForRead()//打开管道文件进行读操作{_fd=open(_fifoname.c_str(),O_RDONLY);if(_fd<0){cout<<"管道文件打开失败"<<endl;}else{cout<<"管道文件打开成功"<<endl;}}void OpenForWrite(){_fd=open(_fifoname.c_str(),O_WRONLY);if(_fd<0){cout<<"管道文件打开失败"<<endl;}else{cout<<"管道文件打开成功"<<endl;}}void Write()//客户端写{string message;int cnt=1;pid_t id=getpid();while(true){cout<<"请输入信息"<<endl;getline(cin,message);message+=(",message number:"+to_string(cnt++)+",["+to_string(id)+"]");write(_fd,message.c_str(),message.length());}}void Read()//服务端读{while(true){char buffer[1024];int number=read(_fd,buffer,sizeof(buffer)-1);if(number>0){buffer[number]=0;cout<<"client say:"<<buffer<<endl;}else if(number==0){cout<<"客户端进程退出,服务端进程也退出"<<endl;break;}else{cout<<"读取错误"<<endl;break;}}}void Close(){if(_fd>0){close(_fd);}}~FillOper(){}
private:string _path;string _name;string _fifoname;int _fd;};

class NamedFifo
{
public:NamedFifo(const string& path,const string& name):_path(path),_name(name){_fifoname=_path+"/"+_name;//创建管道umask(0);int n=mkfifo(_fifoname.c_str(),0666);if(n<0){cout<<"管道创建失败"<<endl;}else{cout<<"管道创建成功"<<endl;}}~NamedFifo(){int n=unlink(_fifoname.c_str());if(n<0){cout<<"管道删除失败"<<endl;}else{cout<<"管道删除成功"<<endl;}}
private:string _path;string _name;string _fifoname;
};

以上NamedFifo类 里面构造命名管道与析构命名管道包含了创建管道和删除管道。


class FillOper
{
public:FillOper(const string& path,const string& name):_path(path),_name(name),_fd(-1){_fifoname=_path+"/"+_name;}void OpenForRead()//打开管道文件进行读操作{_fd=open(_fifoname.c_str(),O_RDONLY);if(_fd<0){cout<<"管道文件打开失败"<<endl;}else{cout<<"管道文件打开成功"<<endl;}}void OpenForWrite(){_fd=open(_fifoname.c_str(),O_WRONLY);if(_fd<0){cout<<"管道文件打开失败"<<endl;}else{cout<<"管道文件打开成功"<<endl;}}void Write()//客户端写{string message;int cnt=1;pid_t id=getpid();while(true){cout<<"请输入信息"<<endl;getline(cin,message);message+=(",message number:"+to_string(cnt++)+",["+to_string(id)+"]");write(_fd,message.c_str(),message.length());}}void Read()//服务端读{while(true){char buffer[1024];int number=read(_fd,buffer,sizeof(buffer)-1);if(number>0){buffer[number]=0;cout<<"client say:"<<buffer<<endl;}else if(number==0){cout<<"客户端进程退出,服务端进程也退出"<<endl;break;}else{cout<<"读取错误"<<endl;break;}}}void Close(){if(_fd>0){close(_fd);}}~FillOper(){}
private:string _path;string _name;string _fifoname;int _fd;};

以上FillOper类里面,OpenForRead()方法是打开管道文件进行读操作,OpenForWrite()方法是打开文件进行写操作,Write()方法是客户端进行写操作,Read()方法是服务端进行读操作。


客户端写

#include "comm.hpp"
int main()
{FillOper wf(PATH,FILENAME);wf.OpenForWrite();wf.Write();wf.Close();return 0;
}

服务端读

#include "comm.hpp"
int main()
{NamedFifo fifo(PATH,FILENAME);FillOper rd(PATH,FILENAME);rd.OpenForRead();rd.Read();rd.Close();return 0;
}

在这里插入图片描述

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

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

相关文章

Spring项目中使用EasyExcel实现Excel 多 Sheet 导入导出功能(完整版)

Excel 多 Sheet 导入导出功能完整实现指南 一、环境依赖 1. Maven 依赖 <!-- EasyExcel --> <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version> </dependency>…

全流程剖析需求开发:打造极致贴合用户的产品

全流程剖析需求开发&#xff1a;打造极致贴合用户的产品 一、需求获取&#xff08;一&#xff09;与用户沟通1.面谈2.问卷调查3.会议讨论 &#xff08;二&#xff09;观察用户工作&#xff08;三&#xff09;收集现有文档 二、需求分析&#xff08;一&#xff09;提炼关键需求&…

SQL语句及其应用(中)(DQL语句之单表查询)

SQL语句的定义: 概述: 全称叫 Structured Query Language, 结构化查询语言, 主要是实现 用户(程序员) 和 数据库软件(例如: MySQL, Oracle)之间交互用的. 分类: DDL: 数据定义语言, 主要是操作 数据库, 数据表, 字段, 进行: 增删改查(CURD) 涉及到的关键字: create, drop, …

5000元组装一台本地运行中、小模型主机,参考配置 (运行DeepSeek、Qwen)

5000元组装一台本地运行中、小模型主机&#xff0c;参考配置 &#xff08;运行DeepSeek、Qwen) 5000元中、小模型主机 DeepSeek、Qwen 各精度模型推荐启动方式 模型名称 参数量 精度 模型大小 推荐运行模式 DeepSeek R1 7b Q4 5 GB LM Studio纯GPU 14b Q4 9 GB LM…

【新手初学】SQL注入getshell

一、引入 木马介绍&#xff1a; 木马其实就是一段程序&#xff0c;这个程序运行到目标主机上时&#xff0c;主要可以对目标进行远程控制、盗取信息等功能&#xff0c;一般不会破坏目标主机&#xff0c;当然&#xff0c;这也看黑客是否想要搞破坏。 木马类型&#xff1a; 按照功…

Containerd+Kubernetes搭建k8s集群

虚拟机环境设置&#xff0c;如果不是虚拟机可以忽略不看 1、安装配置containerd 1.1 添加 Kubernetes 官方仓库 安装cri-tools的时候需要用到 cat > /etc/yum.repos.d/kubernetes.repo << EOF [kubernetes] nameKubernetes baseurlhttps://mirrors.aliyun.com/kub…

应用待机分组管控是啥

1. 应用待机群组是啥&#xff1f; Android 9 引入了一个新功能&#xff0c;叫应用待机群组。简单来说&#xff0c;就是根据你最近使用应用的频率和时间&#xff0c;系统会把应用分成不同的“群组”。每个群组的应用能用的系统资源不一样&#xff0c;比如后台任务、闹钟、网络请…

C/C++后端开发面经

字节跳动 客户端开发 实习 一面(50min) 自我介绍是否愿意转语言,是否只愿意搞后端选一个项目来详细谈谈HTTP和HTTPS有什么区别?谈一下HTTPS加密的具体过程&#xff1a; 非对称加密 对称加密 证书认证的方式 非对称加密是为了保证对称密钥的安全性。 对称…

【第十三届“泰迪杯”数据挖掘挑战赛】【2025泰迪杯】A题解题全流程(持续更新)

【第十三届“泰迪杯”数据挖掘挑战赛】【2025泰迪杯】A题解题全流程-思路&#xff08;持续更新&#xff09; 写在前面&#xff1a; 1、A题、C题将会持续更新&#xff0c;陆续更新发布文章 2、赛题交流咨询Q群&#xff1a;1037590285 3、全家桶依旧包含&#xff1a; 代码、…

如何让 history 记录命令执行时间?Linux/macOS 终端时间戳设置指南

引言:你真的会用 history 吗? 有没有遇到过这样的情况:你想回顾某个重要命令的执行记录,却发现 history 只列出了命令序号和内容,根本没有时间戳?这在运维排查、故障分析、甚至审计时都会带来极大的不便。 想象一下,你在服务器上误删了某个文件,但不知道具体是几点执…

Redis缓存异常场景深度解析:穿透、击穿、雪崩及终极解决方案

一、引言 在高并发系统中&#xff0c;缓存承担着流量洪峰的削峰填谷作用。然而当缓存层出现异常时&#xff0c;可能引发数据库级联崩溃&#xff0c;造成系统瘫痪。本文将深入剖析缓存穿透、缓存击穿、缓存雪崩三大典型问题&#xff0c;并提供企业级解决方案。文章包含7种防御策…

Scala 之 正则

regex 函数提取 import scala.util.matching.Regex// 输入表达式 val expression "[a#0, round(a#0, 0) AS round(a, 0)#1, abs(a#0) AS abs(a)#2, len(cast(a#0 as string)) AS len(a)#3]"// 定义一个正则表达式来提取函数名称 val functionPattern: Regex &quo…

CI/CD-Jenkins安装与应用

CI/CD-Jenkins安装与应用 Docker安装Jenkins docker-compose.yaml version: "3.8" # # 自定义网络配置 # networks:cicd:driver: bridgeservices:jenkins:# 尽量使用新版本的Jenkins, 低版本的Jenkins的有些插件使用不了# jenkins/jenkins:lts-jdk17是长期支持版…

验证Linux多进程时间片切换的程序

​​ 一、软件需求 在同时运行多个CPU密集型进程时&#xff0c;需采集以下统计信息&#xff1a; 当前运行在逻辑CPU上的进程ID每个进程的运行进度百分比 实验程序设计要求&#xff1a; 1. 命令行参数 参数说明示例值n并发进程数量3total总运行时长&#xff08;毫秒&…

IvorySQL:兼容Oracle数据库的开源PostgreSQL

今天给大家介绍一款基于 PostgreSQL 开发、兼容 Oracle 数据库的国产开源关系型数据库管理系统&#xff1a;IvorySQL。 IvorySQL 由商瀚高软件提供支持&#xff0c;主要的功能特性包括&#xff1a; 完全兼容 PostgreSQL&#xff1a;IvorySQL 基于 PostgreSQL 内核开发&#xf…

树莓派超全系列文档--(13)如何使用raspi-config工具其二

如何使用raspi-config工具其二 raspi-configPerformance optionsOverclockGPU memoryOverlay file systemFan Localisation optionsLocaleTime zoneKeyboardWLAN country Advanced optionsExpand filesystemNetwork interface namesNetwork proxy settingsBoot orderBootloader…

QT音乐播放器(1):数据库保存歌曲

实现功能&#xff1a;用数据库保存本地导入和在线搜索的歌曲记录 目录 一. 保存本地添加的歌曲 1. 使用QSettings &#xff08;1&#xff09;在构造函数中&#xff0c;创建对象。 &#xff08;2&#xff09;在导入音乐槽函数中&#xff0c;保存新添加的文件路径&#xff0c…

自动化发布工具CI/CD实践Jenkins常用工具和插件的使用

1、安装常用工具 名称版本备注jdkjava8代码打包所需git1.8.3.1maven3.6.3注意配置私服内容nvm0.39.3多Node.js环境管理工具Node.jsv14.18.0 / v16.17.1包管理工具yarn1.22.15包管理工具 1.1 安装jdk Jenkins 需要使用java11 及以上&#xff0c;但是代码打包依赖jdk8&#xff…

shared_ptr和 weak_ptr的详细介绍

关于 shared_ptr 和 weak_ptr 的详细介绍及使用示例&#xff1a; 1. shared_ptr&#xff08;共享所有权智能指针&#xff09; 核心特性 引用计数&#xff1a;记录当前有多少个 shared_ptr 共享同一个对象。自动释放&#xff1a;当引用计数归零时&#xff0c;自动释放对象内存…

Spring AI MCP 架构详解

Spring AI MCP 架构详解 1.什么是MCP? MCP 是一种开放协议&#xff0c;它对应用程序向大语言模型&#xff08;LLMs&#xff09;提供上下文信息的方式进行了标准化。可以把 MCP 想象成人工智能应用程序的 USB-C 接口。就像 USB-C 为将设备连接到各种外围设备和配件提供了一种…