Linux进程间通信 - 命名管道

news2024/10/5 15:28:47

在之前的文章中我们讲述了匿名管道的原理的以及对应的简单的两个小例子,在本文中,我们将来继续管道的学习 -- 命名管道。

命名管道

  • 管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。
  • 如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。
  • 命名管道是一种特殊类型的文件

可以使用mkfifo来在bash中创建一个管道 :

简要介绍命名管道原理

之前我们在文件相关的内容讲述过引用计数的知识,当有多个文件指向同一个inode时,inode就会++。进程间通信首先需要的就是让两个进程能够看到同一份内容,那么下面我们就来简要的讲述一下如何看到同一份内容:首先一个进程打开一个新的文件,然后当有另一个进程需要打开这个文件的时候,首先需要做的就是,在所有打开的文件列表中查看是否已经打开了该文件,若是已经打开了就将文件结构体中的一个变量ref(引用计数)++。当关闭文件时,先将引用计数--,当引用计数归零时就删除该文件。这样两个进程就看到了在OS中的同一份资源,我们就达到了两个进程看到同一份内容的目标。

在这里与我们之前学习过的普通文件不同,普通文件我们需要定时将文件刷新到磁盘中,而这里的文件不需要这样的操作,只需要在内存中打开,然后让多个进程进行通信, 这种文件也被称为内存级文件(命名管道文件),不会进行刷盘。

如何保证两个毫不相关的进程,看到的是同一个文件。文件的唯一性是用路径来确定的,让不同的进程通过文件路径+文件名看到同一个文件,并打开,就是看到了同一份资源 --- 具备了进程间通信的前提。

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

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

例子-用命名管道实现server&client通信

// comm.hpp
#pragma once

#include <iostream>
#include <string>

#define NUM 1024

const std::string fifoname = "./fifo"; // 文件所在的路径 
uint32_t mode = 0666; // 创建文件的模式 - 权限
// server
#include <iostream>
#include <cerrno>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "comm.hpp"
#include <unistd.h>

int main()
{
    // 1. 创建管道文件,只需要创建一次
    umask(0); // 这个设置不会影响系统的默认配置,只会影响当前进程
    int n = mkfifo(fifoname.c_str(), mode);
    if (n != 0)
    {
        std::cout << errno << " : " <<strerror(errno) << std::endl;
        return 1;
    }

    std::cout << "creat fifo file success" << std::endl;
    
    // 2. 让服务端直接开启管道文件
    int rfd = open(fifoname.c_str(), O_RDONLY);
    if (rfd <= 0)
    {
        std::cout << errno << " : " <<strerror(errno) << std::endl;
        return 2;
    }
    
    std::cout << "open fifo success, begin ipc" << std::endl;

    // 3. 正常通信
    char buffer[NUM];
    while (true)
    {
        buffer[0] = 0;
        ssize_t n = read(rfd, buffer, sizeof(buffer) - 1);
        if (n > 0)
        {
            buffer[n] = '\0';
            std::cout << "client# " << buffer << std::endl;
        }
        else if (n == 0)
        {
            std::cout << "client quit, me too" << std::endl;
            break;
        }
        else
        {
            std::cout << errno << " : " << strerror(errno) << std::endl;
            break;
        }
    }
    close(rfd);
    unlink(fifoname.c_str()); // 对生成的管道文件删除
    std::cout << "管道已成功删除" << std::endl;
    
    return 0;
}
// client
#include <iostream>
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "comm.hpp"
#include <unistd.h>
#include <cassert>

int main()
{
    //1. 不需创建管道文件,我只需要打开对应的文件即可!
    int wfd = open(fifoname.c_str(), O_WRONLY);
    if(wfd < 0)
    {
        std::cerr << errno << ":" << strerror(errno) << std::endl;
        return 1;
    }    
    // 可以进行常规通信了
    char buffer[NUM];
    while(true)
    {
        std::cout << "请输入你的消息# ";
        char *msg = fgets(buffer, sizeof(buffer) - 1, stdin); // 这里不用-1,fgets会自己处理,但是统一 -1,C的接口不用-1,但是其余的接口需要,这里可以进行统一的处理
        assert(msg);
        (void)msg;

        // 处理输入消息时获得的 \n 符号
        buffer[strlen(buffer) - 1] = 0;
        // abcde\n\0
        // 012345
        if(strcasecmp(buffer, "quit") == 0) break; // 忽略大小写进行比较

        ssize_t n = write(wfd, buffer, strlen(buffer)); // 这是往文件里面写不会关心是否有'\0'
        assert(n >= 0);
        (void)n;
    }
    close(wfd);

    return 0;
}

下面就是上述代码运行的结果:从中可以看出当sever端开始运行的时候管道成功创建,但是开没有成功打开,再将客户端运行时,管道就正常的打开并运行。

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

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

相关文章

自动化测试如何做?接口自动化测试如何才能做好?

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口自动化测试常…

大话设计模式——中介者

5. 中介者&#xff08;Mediator&#xff09; Intent 集中相关对象之间复杂的沟通和控制方式。 Class Diagram Mediator&#xff1a;中介者&#xff0c;定义一个接口用于与各同事&#xff08;Colleague&#xff09;对象通信。Colleague&#xff1a;同事&#xff0c;相关对象…

「轻解压」怎么解?小红书用户画像告诉你

“轻养生”、“轻运动”……一个“轻”字&#xff0c;高度概括了如今年轻人面对生活的态度。今年&#xff0c;「轻解压」成为新的主题词&#xff0c;被广泛提及。 相比传统解压方式&#xff0c;轻解压更讲究愉悦感和生活感。用户通过围观开榴莲、沉浸式收纳等看似与解压毫无关…

MySQL数据库+增删改查

文章目录 MySQL数据库1 基本概念2 数据库系统2.1 操作数据库2.2 分类2.3 常见数据类型 3 SQL语句3.1 DDL3.1.1 创建数据库3.1.2 创建表3.1.3 删除数据库3.1.4 删除表3.1.5 查看所有数据库3.1.6 查看数据表 3.2 DML3.2.1 插入数据3.2.2 删除数据3.2.3 更新数据 3.3 DQL3.3.1 显示…

项目管理专业人员能力评价(CSPM)相关问题汇总,看这篇就够了!

问题导览&#xff1a; 1、国标项目管理&#xff08;项目管理专业人员能力评级&#xff09;证书是什么&#xff1f; 2、国标项目管理&#xff08;项目管理专业人员能力评级&#xff09;证书有几级&#xff1f; 3、项目管理专业人员能力等级证书的价值&#xff08;含金量&#…

2023年年度最佳配色就是它-我已经为大家配好了色卡,还不快来用?

洋红或者又称为胭脂红 今年的「洋红万岁」,PANTONE 称其是[非常规时代的非常规红] 它源自 PANTONE 的红色家族,灵感来自一种叫胭脂虫的小昆虫,在色轮上介于红色和粉红色之间,是天然染料家族中最珍贵的染料之一,也是世界上已知的最浓烈、最明亮的染料之一。 据 PANTONE …

oxygen技术文档编写教程

CSS样式 https://www.oxygenxml.com/doc/versions/24.1/ug-editor/topics/dg-css-stylesheet.html &#xff08;其他参考链接&#xff1a;https://zhuanlan.zhihu.com/p/480000063&#xff09; 插件 https://www.oxygenxml.com/addons.html 官方template https://styles.o…

量子网络商业化的时代来了吗?

光子盒研究院 现在&#xff0c;一个利用量子“纠缠”在遥远的用户之间编织亲密联系的全球网络正在开始形成。 ——田纳西州的这个城市曾推出美国第一个全市范围的千兆比特互联网服务。现在&#xff0c;它将推出全美第一个商业化的量子网络。 2010年&#xff0c;查塔努加市因“成…

双功能螯合剂:MeTz-PEG11-NOTA,甲基四嗪十一聚乙二醇NOTA,试剂有哪些特点?

产品描述&#xff1a; MeTz-PEG11-NOTA&#xff08;甲基四嗪-PEG11-NOTA&#xff09;通过PEG进行连接两端甲基四嗪和NOTA&#xff0c;其中亲水性PEG间隔臂提供了一个长而灵活的连接&#xff0c;一定限度地减少了与含四嗪的复合分子连接有关的空间位阻。NOTA及其衍生物具有良好的…

安装PowerDesigner

安装PowerDesigner&#xff08;文章附上安装所需要的安装包&#xff09; 环境&#xff1a;windows10操作系统、PowerDesigner16.5版 1、双击PowerDesigner16.5安装包进行安装 选择Trial&#xff0c;再点击Next&#xff0c;别选错哈 选择hongkong&#xff0c;并且点击agree …

64G超大容量内存条599,光威天策DDR4 32×2原地起飞

- 光威天策DDR4 64G套装&#xff0c;599元享受极速体验 - 599元升级64G内存&#xff0c;光威天策DDR4给你惊喜 - 光威天策DDR4 64G内存条&#xff0c;简约外观&#xff0c;强劲性能 - 超值618&#xff0c;光威天策DDR4 64G内存条&#xff0c;速度快&#xff0c;散热好 很多热爱…

企业想要搭建CRM平台该如何操作?

如今&#xff0c;企业数字化转型的浪潮依然汹涌。而CRM客户管理平台是企业实现数字化转型&#xff0c;提升市场竞争力的重要工具。那么&#xff0c;企业如何搭建CRM客户管理平台&#xff1f;下面我们就这个问题来说一下。 一、明确业务目标和需求 企业需要明确业务目标&#…

在 Blender、ZBrush 和 Substance 3D Painter 中创建幻想角色

今天瑞云渲染小编给大家带来一篇关于Obafunso Dorgu 作者Serenity 项目背后的工作流程&#xff0c;告诉我们这些衣服是如何在 Marvelous Designer 中制作的&#xff0c;并提到了设置逼真的头发的重要事项。 介绍 大家好&#xff0c;我叫Obafunso Dorgu&#xff0c;我是一名自…

Python+Appium实现自动化测试的使用步骤

这篇文章主要介绍了PythonAppium实现自动化测试的使用步骤&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧 一、环境准备 1.脚本语言&#xff1a;Python3.x IDE&am…

【数据分享】1929-2022年全球站点的逐年平均能见度(Shp\Excel\12000个站点)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到常用的能见度数据&#xff0c;最详细的能见度数据是具体到气象监测站点的能见度数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929…

有趣的数学 对称/非对称加密简史及数学原理一览

一、非对称加密简史 1、算法建立 对于任何想发送加密信息的人&#xff0c;另一个问题是如何让接收人知道这条信息一开始是如何加密的。对于像字母替换式密码这样的密码&#xff0c;问题在于&#xff0c;一旦窃听者知道了加密方案&#xff0c;后续的信息都可以轻松获取。 公钥加…

【北邮国院大三下】Intellectual Property Law 知识产权基础 Week4

北邮国院大三电商在读&#xff0c;随课程进行整理知识点。仅整理PPT和相关法条中相对重要的知识点&#xff0c;个人认为相对不重要的细小的知识点不列在其中。如有错误请指出。转载请注明出处&#xff0c;祝您学习愉快。 如需要pdf格式的文件请私信联系或微信联系 PRC是否inf…

Android Framework分析Launcher启动过程

简介&#xff1a; Launcher是Android系统中默认的桌面应用程序&#xff0c;负责管理设备的屏幕和应用程序图标。本文将详细介绍Launcher的启动过程&#xff0c;并使用源代码示例进行说明。 Launcher的启动过程&#xff1a; 下面是Launcher的启动过程的详细步骤&#xff1a; …

开源软件介绍——开源基金会和开源许可证

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天我们来看一看世界范围内知名的开源基金会和开源许可证。 开源基金会 基金会是开源生态中的一个重要组成部分&#xff0c;用于资金的筹集与开源项目的前期资助与后期的发展。这里将介绍部分重要基金会&am…

嵌入式Linux时间同步 gpsd+chrony+pps

硬件设计 GNSS模块输出pps到CPU&#xff0c;1PPS_1.8V用于V2X的pps&#xff0c;GPIO35_1.8V用于pps-gpio。这里做了pps一分二&#xff0c;由于距离太近不影响功能&#xff0c;焊接R35 0欧电阻。 驱动配置 gps_pps_pins:ublox_gps2 {leadcore,pins "gpio34";leadcore…