進程間通信2(命名管道)linux

1 命名管道

前面講到匿名管道,有一個很大的限制,那就是只有具有相同祖先(具有親緣關系)的進程間才能進行通信,但是如果想實現不同進程間的通信,這個時候命名管道就發揮著巨大作用。

命名管道是一種特殊類型的文件,和匿名管道不一樣的是這個命名管道是有文件名的,有路徑的,有對應的inode,只是不用向磁盤中進行IO。

多個進程是否可以打開同一個文件呢?這個問題在前面講文件描述符時,就已經知道是可以的,例如:顯示器文件,多個進程都可以打開,并向顯示器寫入。

1.1 創建命名管道

命令行創建:

mkfifo filename

系統調用創建:

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

參數為:創建管道的文件名,權限。?

1.2 匿名管道和命名管道使用不同

匿名管道由pipe函數創建并打開

命名管道由mkfifo函數創建,打開用open

FIFO(命名管道)與pipe(匿名管道)之間唯一區別在它們創建與打開的方式不同,?但這些工作完成之后,它們具有相同的語義。

2 用命名管道實現server與client之間的通信

讀寫端共同包含的部分:

common.hpp

#pragma once
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <string>
#include <fcntl.h>
#include <unistd.h>const std::string filename="fifo";
const int mode=0666;const int size=1024;

權限,默認文件名。

namepipe類

默認構造函數

namepipe(const std::string &filename) : _filename(filename),_fd(defaultfd){}

成員_fd表示文件描述符,所以要得等到,打開文件時再確認,這里默認為-1。

初始化創建管道文件

bool InitNamepipe(){int n = mkfifo(filename.c_str(), mode);if (n == 0){std::cout << "mkfifo success " << std::endl;}else{perror("mkfifo");return false;}return true;}

利用mkfifo函數創建一個管道。

這里要注意一個從管道中寫入數據,一個向管道中讀取數據,所以就要有兩種打開方式:

也就是在open函數設置不同的權限

讀打開

bool OpenForRead(){_fd = open(filename.c_str(), O_RDONLY);if (_fd < 0){perror("open");return false;}else{std::cout << "open success: " << _fd << std::endl;}return true;}

寫打開

 bool OpenForWrite(){_fd = open(filename.c_str(), O_WRONLY);if (_fd < 0){perror("open");return false;}else{std::cout << "open success: " << _fd << std::endl;}return true;}

讀數據

 void Write(const std::string &in){write(_fd, in.c_str(), in.size());}

寫數據

bool Read(std::string *out){char buffer[size] = {0};ssize_t num = read(_fd, buffer, sizeof(buffer) - 1);if (num > 0){buffer[num] = 0;*out = buffer;}else if (num == 0){std::cout << "write out,me too" << std::endl;return false;}else{return false;}return true;}

讀取數據失敗或寫端關閉返回false,這里out是一個輸出型參數,將讀出的數據通過out帶出。

這里read也是默認阻塞等待寫端寫入。

回收資源

關閉文件描述符:

void Close(){if(_fd==defaultfd)return;elseclose(_fd);}

防止沒有打開文件,就直接close,所以這里有一個defaultfd的操作。

刪除管道文件:

void Remove(){int m=unlink(_filename.c_str());(void)m;}

namepipe.hpp

#pragma once
#include "common.hpp"const int defaultfd = -1;class namepipe
{
public:namepipe(const std::string &filename) : _filename(filename),_fd(defaultfd){}bool InitNamepipe(){int n = mkfifo(filename.c_str(), mode);if (n == 0){std::cout << "mkfifo success " << std::endl;}else{perror("mkfifo");return false;}return true;}bool OpenForRead(){_fd = open(filename.c_str(), O_RDONLY);if (_fd < 0){perror("open");return false;}else{std::cout << "open success: " << _fd << std::endl;}return true;}bool OpenForWrite(){_fd = open(filename.c_str(), O_WRONLY);if (_fd < 0){perror("open");return false;}else{std::cout << "open success: " << _fd << std::endl;}return true;}void Write(const std::string &in){write(_fd, in.c_str(), in.size());}bool Read(std::string *out){char buffer[size] = {0};ssize_t num = read(_fd, buffer, sizeof(buffer) - 1);if (num > 0){buffer[num] = 0;*out = buffer;}else if (num == 0){std::cout << "write out,me too" << std::endl;return false;}else{return false;}return true;}void Close(){if(_fd==defaultfd)return;elseclose(_fd);}void Remove(){int m=unlink(_filename.c_str());(void)m;}~namepipe(){}private:std::string _filename;int _fd;
};

client

#include"namepipe.hpp"int main()
{namepipe pipe(filename);pipe.OpenForWrite();while(true){std::string in;std::getline(std::cin,in);pipe.Write(in);}pipe.Close();
}

client端發送數據。

server

#include"namepipe.hpp"int main()
{namepipe pipe(filename);pipe.InitNamepipe();pipe.OpenForRead();while(true){std::string* out;if(pipe.Read(out))std::cout<<*(out)<<std::endl;elsebreak;}pipe.Close();pipe.Remove();return 0;
}

server端讀數據。

結果演示:

?

在client端輸入數據,server就可以看到對應的讀取數據。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/85847.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85847.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/85847.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

簡單通過SenseVoice給自己配置一個語音轉文字服務

首先把代碼下載下來 gitgithub.com:FunAudioLLM/SenseVoice.git 然后寫一個docker文件 FROM ubuntu:latestRUN apt-get update -y RUN apt-get install -y python3-full python3-pip RUN mkdir -p /SenseVoice WORKDIR /SenseVoice RUN python3 -m venv . ENV USE_CUDA0 EXP…

網絡釣魚攻擊

?根據2023年Proofpoint年度網絡釣魚報告顯示&#xff1a;91%的針對性攻擊始于釣魚郵件&#xff0c;平均每30秒就有一個企業成為攻擊目標&#xff0c;全球損失超過$6.5B? 一、釣魚攻擊技術深度解析 1. 釣魚攻擊核心技術架構 2. 現代釣魚技術演進 ?攻擊向量升級路線? ?當前…

uvicorn api:app --host 0.0.0.0 --port 7777容器運行失敗

docker logs pycorrector-container-gpu 你這個報錯的核心是&#xff1a; ERROR: Error loading ASGI app, Could not import module "api".這說明&#xff1a; uvicorn api:app 沒有找到 api.py 文件&#xff0c;或者沒法導入 app 對象。 &#x1f50d; 一步步排查…

熱成像儀測MOSFET溫度

熱成像儀測MOSFET溫度 根據提供的搜索結果&#xff0c;熱測量方法主要分為非接觸式和接觸式兩大類&#xff0c;針對不同材料特性和測量場景各有優勢。以下是核心方法的總結及關鍵技術要點&#xff1a; &#x1f525; 一、非接觸式熱測量方法 紅外熱成像技術 原理&#xff1a;通…

Dagster資產元數據與標簽:數據治理的利器

在現代數據棧中&#xff0c;有效的數據治理至關重要。Dagster作為領先的數據編排平臺&#xff0c;提供了強大的資產元數據和標簽功能&#xff0c;幫助團隊更好地理解、組織和跟蹤數據資產。本文將深入探討Dagster中的資產元數據和標簽功能&#xff0c;展示如何利用這些功能提升…

基于物聯網的智能飲水機系統設計

標題:基于物聯網的智能飲水機系統設計 內容:1.摘要 隨著物聯網技術的快速發展&#xff0c;智能設備在日常生活中的應用越來越廣泛。本研究的目的是設計一種基于物聯網的智能飲水機系統&#xff0c;以提高飲水機的使用便捷性和智能化程度。方法上&#xff0c;通過傳感器實時監測…

DP讀書:NEC年終小結和顯示器【明基rd28u】

一點真實體驗_寫在ROBOCON2025國賽前 很久沒有寫這種關于感受的博客了&#xff0c;就用真實感受的角度來看看一次眾測的經歷&#xff0c;哈哈^ 差不多一個月前&#xff0c;我收到了明基的28寸顯示器&#xff0c;體驗了差不多2周左右&#xff0c;一直把顯示器掛在實驗室倉庫La…

Solana 一鍵冷分倉機制詳解:如何用技術手段構建健康的持倉結構

在 Solana 的快速發幣環境中&#xff0c;許多項目方在成功部署代幣后&#xff0c;會面臨一個共通問題——如何避免持倉結構過于集中。無論是初始鑄造的 Token、流動性預留份額&#xff0c;還是空投分發的準備金&#xff0c;如果長時間停留在單一錢包地址中&#xff0c;將在鏈上…

【智能體】dify部署本地步驟

從git克隆倉庫到本地 git clone https://github.com/langgenius/dify.git設置環境變量 cd dify cd docker cp .env.example .envdocker啟動 docker compose up -d在瀏覽器打開網址 http://localhost/install 登錄后即可使用

開源鴻蒙6.0 Beta1版本發布!深圳觸覺智能即將適配RK3566/RK3568/RK3576/RK3588等芯片

開放原子開源鴻蒙&#xff08;OpenAtom OpenHarmony&#xff0c;簡稱“開源鴻蒙”或“OpenHarmony”&#xff09;6.0 Beta1版本正式發布。相比5.1.0 Release版本進一步增強ArkUI組件能力&#xff0c;提供更安全、更靈活的組件布局&#xff1b;增強分布式數據管理能力&#xff0…

機器學習 (ML) 基礎入門指南

一、機器學習概述 &#xff08;一&#xff09;定義 在當今科技飛速發展的時代&#xff0c;機器學習作為人工智能的一個重要分支&#xff0c;正深刻地改變著我們的生活和工作方式。根據機器學習泰斗、卡耐基梅隆大學的湯姆米切爾 (Tom Mitchell) 教授的定義&#xff0c;機器學…

基于ARM ubuntu如何進行交叉編譯

場景總結&#xff1a; 平臺&#xff1a;x86 主機 工具鏈&#xff1a;aarch64-linux-gnu-gcc&#xff08;用于編譯 64-bit ARM 程序&#xff09; 目標&#xff1a;讓 gcc 自動使用 ARM Ubuntu rootfs 中的頭文件和庫&#xff08;位于 /opt/arm64-ubuntu&#xff09; 不希望每…

java+vue+SpringBoo社區藥房系統(程序+數據庫+報告+部署教程+答辯指導)

源代碼數據庫LW文檔&#xff08;1萬字以上&#xff09;開題報告答辯稿ppt部署教程代碼講解代碼時間修改工具 技術實現 開發語言&#xff1a;后端&#xff1a;Java 前端&#xff1a;vue框架&#xff1a;springboot數據庫&#xff1a;mysql 開發工具 JDK版本&#xff1a;JDK1.…

VS2022打Unity中的腳本斷點時出現當前不會命中斷點,找不到相應位置

今天遇到一個很傻的問題&#xff0c; 在新電腦中安裝了Unity和VS2022后&#xff0c;在Unity中打開一個新腳本&#xff0c;打斷點時報警告&#xff0c;如下&#xff1a; 原來在Unity中新建的腳本&#xff0c;如果沒有被使用&#xff0c;就會出現找不到位置的錯誤&#xff01; 反…

UVA489劊子手游戲

UVA489 劊子手的游戲 Hangman Judge - 洛谷 #include <bits/stdc.h> using namespace std;bool arr[26]; int main() {int n;while (cin >> n && n ! -1){string s1, s2;memset(arr, 0, sizeof(arr));cout << "Round " << n <&l…

bat腳本抓取android日志

一 通過bat腳本抓取日志到windows電腦本地 1 通過包名抓取日志 echo off chcp 65001 >nul echo 獲取 com.starauto.ac 的 PID… FOR /F “delims” %%i IN (‘adb shell pidof com.starauto.ac’) DO set PID%%i echo 當前 PID: %PID% echo 開始抓取日志&#xff0c;僅限…

java開發為什么要分層

在 Java 開發中,分層架構(Layered Architecture)是一個常見的設計模式,它將系統分為不同的層級(如表示層、業務邏輯層、數據訪問層等),每個層次都有不同的職責和功能。分層架構的設計能夠帶來很多好處,下面是一些主要原因: 1. 提高代碼的可維護性 模塊化:通過將系統…

通達信 主力攻擊信號系統幅圖指標

通達信 主力攻擊信號系統幅圖指標 用法說明: 該指標用于識別股票或交易品種在短期內的主力資金介入信號,結合趨勢強度及多維度技術條件,幫助投資者捕捉潛在的上漲機會。 核心邏輯: 趨勢確認:要求價格處于20日均線之上,且均線呈上升態勢,確保短期趨勢偏多。 多信號共振…

Nuscences轉kitti數據集格式nuscenes2kitti,以及.bin文件可視化

1.首先去官網下載對應的工具庫https://github.com/linClubs/nuscenes2kitti.git 2.官網有具體的教程&#xff0c;不過編譯的時候需要刪除nus2kitti_ws/src的Cmake文件&#xff0c;除此之外在命令窗口進行軟鏈接export LD_PRELOAD/usr/lib/x86_64-linux-gnu/libffi.so.7 3.詳細…

[設計模式]創建型模式-單例模式

前言 單例模式是最簡單的一種模式。在Go中&#xff0c;單例模式指的是全局只有一個實例&#xff0c;并且它負責創建自己的對象。單例模式有減少內存和系統資源開銷、防止多個實例產生沖突等優點。 因為單例模式保證了實例的全局唯一性&#xff0c;并且只被初始化一次&#xf…