进程间通信-命名管道

news2024/11/15 18:01:25

目录

原理

代码 

简单通信

回归概念 


原理

mkfifo 是 Linux 系统中的一个命令,用于创建命名管道(named pipe),也称为 FIFO(First In, First Out)。命名管道是一种特殊类型的文件,用于进程间通信(IPC)。它允许一个进程将数据写入管道,而另一个进程可以从管道中读取这些数据。


创建一个命名管道文件(p);

pathname 是该函数的一个参数,用于指定要创建的命名管道的路径和文件名。这个路径可以是绝对路径或相对路径,具体取决于你的需求。

 当你使用 echo "i am i named fifo" > myfifo 命令时,它会被挂起,原因是 myfifo 是一个命名管道(FIFO)。命名管道需要有另一个进程从管道中读取数据,才能完成写入操作。如果没有其他进程读取 myfifo,echo 命令会被阻塞,直到有进程读取管道中的数据。

代码 

代码创建named pipe:

 删除named pipe:

在 C 语言中,unlink 函数用于删除文件或命名管道。它的功能是从文件系统中移除一个文件名,但并不立即删除文件数据直到所有引用该文件的数据描述符都被关闭。unlink 也可以用于删除一个命名管道(FIFO)


注意:
删除文件: unlink 只删除文件名,而不是立即删除文件数据。如果其他进程仍然打开该文件的描述符,文件数据将保持在磁盘上,直到所有文件描述符被关闭。
删除命名管道: 对于命名管道,unlink 删除的是管道的路径名,但不会立即影响正在使用该管道的进程。如果有进程正在读写该命名管道,管道本身的缓冲区不会立即被清除,直到所有打开的文件描述符关闭。

#pragma once
#include <iostream>
#include <string>
#include <cstdio>
#include <cerrno>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

const std::string commpath = "./myfifo"; // 两个进程要通过共同的路径访问进程


int creatnamedpipe(const std::string &path)
{
    int res = mkfifo(path.c_str(), 0666); // 注意的是mkfifo要求的是c语言风格的字符串,所以用c_str(),默认文件权限
    if (res != 0)
    {
        perror("mkfifo"); // 管道创建失败会设置错误码
        // In the case of an error,-1 is returned (in which case, errno is set appropriately).
    }
    return res;
}
int removenamedpipe(const std::string &path)
{
    int res = unlink(path.c_str());
    if (res != 0)
    {
        perror("unlink"); // 移除失败会设置错误码
        //On error, -1 is returned, and errno is set appropriately.
    }
    return res;
}
#include"namedpipe.hpp"
//read
int main(){
    creatnamedpipe(commpath);
    sleep(5);
    removenamedpipe(commpath);
    return 0;
}

简单通信

serve.cc

#include "namedpipe.hpp"
// read
int main()
{
    namedpipe fifo(commpath, creater); // 告诉在哪里创建和身份
    //对于读端而言,如果我们打开文件但是写端还没来,我们可以打开但是我会阻塞在open调用中,直到对方打开;匿名管道不会存在这种情况
    //相当于变相的进程同步
    if (fifo.openforread())
    { // 打开成功
        while (true)
        {                        // 一直读
            std::string message; // 读的信息
            int n = fifo.readnamepipe(&message);
            if (n > 0)
            {
                std::cout << "client say : " << message << std::endl;
            }
            else if (n == 0)
            { // 对于读端来讲,如果写端关闭,读端再读就会读到零,代表读到文件结尾
                std::cout << " client quit, serve too ! " << std::endl;
                break;
            }
            else
            { // 出错了
                std::cout << "fifo.readnamepipe error " << std::endl;
                break;
            }
        }
    }
    return 0;
}

 client.cc

#include "namedpipe.hpp"
// write
int main()
{
    namedpipe fifo(commpath, user);
    if (fifo.openforwrite())
    { // 打开成功
    while(true){
        std::cout << "user write : ";
        std::string message; // 用户输入的message
        std::getline(std::cin, message);
        fifo.writenamepipe(message);
    }
    }
    return 0;
}

 namedpipe.hpp

#pragma once
#include <iostream>
#include <string>
#include <cstdio>
#include <cerrno>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

const std::string commpath = "./myfifo"; // 两个进程要通过共同的路径访问进程

#define defaultfd -1
#define creater 1
#define user 2
#define Read O_RDONLY
#define Write O_WRONLY
#define basesize 1024 // 缓冲区默认

class namedpipe
{        // 用一个类来实现,不用函数了
private: // 不让外界看到基础的打开方式
    bool opennamedpipe(int mode)
    { // mode为打开文件的模式
        _fd = open(_fifo_path.c_str(), mode);
        if (_fd < 0)
        {
            return false;
        }
        return true;
    }

public:
    namedpipe(const std::string &path, int who) // 路径和名称,代表谁
        : _fifo_path(path), _id(who), _fd(defaultfd)
    {
        if (_id == 1)
        {                                               // 是创建者才能创建管道
            int res = mkfifo(_fifo_path.c_str(), 0666); // 注意的是mkfifo要求的是c语言风格的字符串,所以用c_str(),默认文件权限
            if (res != 0)
            {
                perror("mkfifo"); // 管道创建失败会设置错误码
                // In the case of an error,-1 is returned (in which case, errno is set appropriately).
            }
            std::cout << "creater cteat pipe " << std::endl;
        }
    }
    bool openforread()
    { // 打开读
        return opennamedpipe(Read);
    }
    bool openforwrite()
    { // 打开写
        return opennamedpipe(Write);
    }
    int readnamepipe(std::string *out)
    {                                              // 输出型
        char buffer[basesize];                     // 缓冲区,大小设置
        int n = read(_fd, buffer, sizeof(buffer)); // 读
        if (n > 0)
        {
            buffer[n] = 0;
            *out = buffer; // 带出去
        }
        return n;
    }
    int writenamepipe(const std::string &in)
    {                                      // 输入型
        return write(_fd, in.c_str(), in.size()); // 写
    }
    ~namedpipe()
    { // 析构
        if (_id == 1)
        { // 是创建者才能删除管道
            sleep(5);
            int res = unlink(_fifo_path.c_str());
            if (res != 0)
            {
                perror("unlink"); // 移除失败会设置错误码
                // On error, -1 is returned, and errno is set appropriately.
            }
            std::cout << "creater kill pipe " << std::endl;
        }
        if (_fd != defaultfd)
            close(_fd);
    }

private:
    const std::string _fifo_path;
    int _id; // 当前使用这个管道的人的身份
    int _fd; // 文件描述符
};

回归概念 

让不同的进程看到同一份资源------命名管道------通过文件路径

 如果vscode显示一直输入密码但是连接不上,可以试试这种方法;
可以了  是那个vscode-server文件有问题  有时候会出现垃圾数据导致不能连接

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

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

相关文章

从0到1!本地部署一个大语言模型!完整方法!

要想从零开始部署一个**大语言模型&#xff08;LLM&#xff09;**到本地&#xff0c;不仅仅是硬件上安装软件包&#xff0c;还需要对模型选择、优化和应用搭建有一定的理解。下面是一份完整教程&#xff0c;手把手带你走过如何在本地环境中部署LLM。 1. 了解部署需求与硬件准备…

交换机链路聚合

一、概述 通过链路聚合&#xff0c;可以提高链路的可靠性&#xff0c;提升链路带宽。链路具有一般有手工模式和LACP模式。 二、拓扑图 三、实操演练 1、手工模式 手工模式一般用于老旧、低端设备。 缺点&#xff1a; &#xff08;1&#xff09;为了使链路聚合接口正常工作…

brew install node提示:Error: No such keg: /usr/local/Cellar/node

打开本地文件发现Cellar目录下无法生成 node文件&#xff0c;应该是下载时出现问题&#xff0c;重复下载无法解决问题&#xff0c;只能重新安装brew。 步骤1&#xff08;安装 brew&#xff09;&#xff1a; /bin/zsh -c “$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/ra…

打造高效实时数仓,从Hive到OceanBase的经验分享

本文作者&#xff1a;Coolmoon1202&#xff0c;大数据高级工程师&#xff0c;专注于高性能软件架构设计 我们的业务主要围绕出行领域&#xff0c;鉴于初期采用的数据仓库方案面临高延迟、低效率等挑战&#xff0c;我们踏上了探索新数仓解决方案的征途。本文分享了我们在方案筛选…

uniapp离线(本地)打包

安卓离线打包 注意&#xff1a;jdk建议选择1.8 下载Android Studio配置gradle仓库地址 第一步&#xff1a;先下载对应的版本&#xff0c;进行压缩包解压 第二步&#xff1a;在电脑磁盘&#xff08;D盘&#xff09;&#xff0c;创建文件夹存放压缩包并进行解压&#xff0c;并创…

8.8canny算子检测

目录 实验原理 示例代码 运行结果 实验原理 在OpenCV中&#xff0c;Canny边缘检测是一种广泛使用的边缘检测算法。它是由John F. Canny在1986年提出的&#xff0c;并且因其性能优良而被广泛应用。在OpenCV中&#xff0c;Canny边缘检测是通过Canny函数实现的。 函数原型 v…

【爬虫软件】小红书按关键词批量采集笔记,含笔记正文、转评赞藏等!

一、背景介绍 1.1 爬取目标 熟悉我的小伙伴都了解&#xff0c;我之前开发过2款软件&#xff1a; 【GUI软件】小红书搜索结果批量采集&#xff0c;支持多个关键词同时抓取&#xff01; 【GUI软件】小红书详情数据批量采集&#xff0c;含笔记内容、转评赞藏等&#xff01; 现在…

HuggingFists算子能力扩展-PythonScript

HuggingFists作为一个低代码平台&#xff0c;很多朋友会关心如何扩展平台算子能力。扩展平台尚不支持的算子功能。本文就介绍一种通过脚本算子扩展算子能力的解决方案。 HuggingFists支持Python和Javascript两种脚语言的算子。两种语言的使用方式相同&#xff0c;使用者可以任选…

C++速通LeetCode简单第3题-相交链表

简单解&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {Li…

ACL-latex模板中参考文献出现下划线---由于宏包的冲突

% \usepackage{ulem} %加入后造成参考文献有下划线&#xff0c;正常情况是没有的。 别的包也可能造成此情况&#xff0c;可以仔细检查。 如下图所示&#xff1a; \usepackage{ulem}在LaTeX中的作用主要是提供了一系列用于文本装饰和强调的命令。ulem宏包由Donald Arseneau…

移动订货小程序哪个好 批发订货系统源码哪个好

订货小程序就是依托微信小程序的订货系统&#xff0c;微信小程序订货系统相较于其他终端的订货方式&#xff0c;能够更快进入商城&#xff0c;对经销商而言更为方便。今天&#xff0c;我们一起盘点三个主流的移动订货小程序&#xff0c;看看哪个移动订货小程序好。 第一、核货宝…

Redis搭建集群

功能概述 Redis Cluster是Redis的自带的官方分布式解决方案&#xff0c;提供数据分片、高可用功能&#xff0c;在3.0版本正式推出。 使用Redis Cluster能解决负载均衡的问题&#xff0c;内部采用哈希分片规则&#xff1a; 基础架构图如下所示&#xff1a; 图中最大的虚线部分…

AI基础 L19 Quantifying Uncertainty and Reasoning with Probabilities I 量化不确定性和概率推理

Acting Under Uncertainty 1 Reasoning Under Uncertainty • Real world problems contain uncertainties due to: — partial observability, — nondeterminism, or — adversaries. • Example of dental diagnosis using propositional logic T oothache ⇒ C av ity • H…

Tomact的基本使用

一.Web服务器 Web服务器是一个软件程序,对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让web开发更加便捷.主要功能是"提供网上信息浏览服务" 二.将Demo程序部署到webapps 直接复制进webapps目录,然后打开浏览器来进行访问 基于tomact服务器部署的项…

PCL 读取STL文件转换为点云

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2数据显示 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff08;长期更新&#xff09; 一、概述…

结构开发笔记(八):solidworks软件(七):装配图中让摄像头绕轴旋转起来

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/142176639 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

petalinux开发 添加iperf

如何把iperf编译到petalinux工程中去 目录&#xff1a; /home/xxx/7z020/project-spec/meta-user/conf 里面有一个user-rootfsconfig文件 它默认里面有 CONFIG_gpio-demo CONFIG_peekpoke 把iperf添加进去 #Note: Mention Each package in individual line #These packages w…

101.WEB渗透测试-信息收集-FOFA语法(1)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;100.WEB渗透测试-信息收集-网络空间搜索引擎shodan&#xff08;2&#xff09;-CSDN博客 F…

理解 C 语言:从基础到高级的全面介绍

前言特性指针结构体动态内存管理文件操作 习题书籍推荐本书内容 前言 C语言是一种通用的编程语言&#xff0c;广泛应用于系统编程、嵌入式系统以及各种高性能应用程序的开发。它的设计理念和语法结构为许多现代编程语言奠定了基础。本文将深入探讨 C 语言的基本概念、关键特性、…

QT 中使用QXlsx 读写文件

PC 工具中需要操作xlsx格式的数据&#xff0c;前面使用的是QAxObject&#xff0c;需要一些设置&#xff0c;还要安装office的控件或者wps的控件&#xff0c;在一些电脑上面有的时候还会有异常&#xff0c;后面发现一个好像的开源库QXls&#xff0c;发现读写的速度比以前快&…