【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.pswp.cn/bicheng/74946.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74946.shtml
英文地址,請注明出處:http://en.pswp.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 為將設備連接到各種外圍設備和配件提供了一種…