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…