【Linux】命名管道

news2025/1/19 17:21:42

文章目录

  • 命名管道
      • 一、命名管道的原理
      • 二、命名管道的创建
          • 命令行中创建
          • 程序中创建 - mkfifo函数:
      • 三、命名管道的使用
          • 命名管道实现server&client通信
      • 四、匿名管道与命名管道的区别

命名管道

如果涉及到在文件系统中创建一个有名的管道,那么就是在使用命名管道。

一、命名管道的原理

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

注意:
普通文件是很难做到通信的,即便做到通信也无法解决一些安全问题。
命名管道和匿名管道一样,都是内存文件,只不过命名管道在磁盘有一个简单的映像,但这个映像的大小永远为0,因为命名管道和匿名管道都不会将通信数据刷新到磁盘当中。

二、命名管道的创建

命令行中创建

在命令行中,可以使用mkfifo命令创建命名管道。mkfifo命令的语法如下:

mkfifo [OPTION]... NAME...

其中,OPTION是可选的参数,而NAME是要创建的命名管道的名称。以下是一个简单的示例:

mkfifo fifo

请添加图片描述

这会在当前目录下创建一个名为 fifo 的命名管道。命名管道的创建后,可以像文件一样对待,可以通过其他命令或程序来读取和写入,但是。

程序中创建 - mkfifo函数:

mkfifo函数是一个库函数,它是由C标准库提供的,而不是直接调用底层操作系统的系统调用。在C语言中,可以使用mkfifo系统调用来在程序中创建命名管道。该系统调用的函数原型如下:

#include <sys/types.h>
#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);
  • pathname 参数是命名管道的路径和名称。
  • mode 参数是权限位,用于指定文件权限。
    当然,实际上创建出来文件的权限值还会受到umask(文件默认掩码)的影响,实际创建出来文件的权限为:mode&(~umask)。umask的默认值一般为0002,如果我们设置mode值为0666时,则实际创建出来文件的权限为0664。

三、命名管道的使用

命名管道实现server&client通信

实现服务端(server)和客户端(client)之间的通信之前,我们需要先让服务端运行起来,让服务端运行后创建一个命名管道文件,然后客户端再以读的方式打开该命名管道文件,之后服务端就可以从该命名管道当中读取客户端发来的通信信息了。

服务端的代码,server.cpp 如下:

#include "comm.h"

using namespace std;

int main()
{
    int n = mkfifo(FILENAME, 0666);
    if (n < 0)
    {
        cerr << "mkfifo failed, errno: " << errno << ", errstring:" << strerror(errno) << endl;
        return 1;
    }
    cout << "mkfifo success..." << endl;

    int rfd = open(FILENAME, O_RDONLY);
    if (rfd < 0)
    {
        cerr << "errno: " << errno << ", errstring:" << strerror(errno) << endl;
        return 2;
    }
    cout << "open fifo success..." << endl;

    char buffer[1024];
    while (true)
    {
        ssize_t s = read(rfd, buffer, sizeof(buffer) - 1);
        if (s > 0)
        {
            buffer[s] = '\0';
            cout << "Client say# " << buffer << endl;
        }
    }

    close(rfd);
    cout << "close fifo success..." << endl;

    return 0;
}

客户端的代码,如下:

#include "comm.h"

using namespace std;

int main()
{
    int wfd = open(FILENAME, O_WRONLY);
    if (wfd < 0)
    {
        cerr << "errno: " << errno << ", errstring:" << strerror(errno) << endl;
        return 1;
    }

    string message;
    while (true)
    {
        cout << "Please Enter# ";
        getline(cin, message);

        ssize_t s = write(wfd, message.c_str(), message.size());
        if (s < 0)
        {
            cerr << "errno: " << errno << ", errstring:" << strerror(errno) << endl;
            return 2;
        }
    }

    close(wfd);
    std::cout << "close fifo success..." << std::endl;

    return 0;
}

让客户端和服务端包含同一个头文件,该头文件当中提供这个共用的命名管道文件的文件名和共用的头文件。

// comm.h
#pragma once

#include <cerrno>
#include <cstdio>
#include <string>
#include <iostream>
#include <cstring>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
  
#define FILENAME "myfifo" //让客户端和服务端使用同一个命名管道

先将服务端进程运行起来,之后我们就能在客户端看到这个已经被创建的命名管道文件:
请添加图片描述

请添加图片描述

使用ps axj搭配grep来查询这两个进程:

ps axj | head -1 && ps axj| grep -E '\./server|\./client' | grep -v grep

请添加图片描述

发现这两个进程确实是两个毫不相关的进程,因为它们的PID和PPID都不相同。也就证明了,命名管道是可以实现两个毫不相关进程之间的通信的。

有个小问题是,如果跑完一次想要再运行,命名管道文件mypipe还依然存在,会引发报错程序直接退出:
请添加图片描述


优化一下server.cpp:

#include "comm.h"

using namespace std;

bool MakeFifo()
{
   int n = mkfifo(FILENAME, 0666);
   if (n < 0)
   {
       cerr << "mkfifo failed, errno: " << errno << ", errstring:" << strerror(errno) << endl;
       return false;
   }
   cout << "mkfifo success..." << endl;
   return true;
}

int main()
{
Start:
   int rfd = open(FILENAME, O_RDONLY);
   if (rfd < 0) // 优化:如果open失败,就创建fifo管道文件,然后回到start再open
   {
       cerr << "errno: " << errno << ", errstring:" << strerror(errno) << endl;
       if (MakeFifo())
           goto Start;
       else
           return 1;
   }
   cout << "open fifo success..." << endl;

   char buffer[1024];
   while (true)
   {
       ssize_t s = read(rfd, buffer, sizeof(buffer) - 1);
       if (s > 0)
       {
           buffer[s] = '\0';
           cout << "Client say# " << buffer << endl;
       }
   }

   close(rfd);
   cout << "close fifo success..." << endl;

   return 0;
}

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

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

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

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

相关文章

【c语言】详解操作符(下)

前言&#xff1a; 在上文中&#xff0c;我们已经学习了 原码、反码、补码、移位 操作符、移位操作符、位操作符、逗号表达式、下标访问[ ]、函数调用&#xff08; &#xff09;&#xff0c;接下来我们将继续学习剩下的操作符。 1. 结构成员访问操作符 1.1 结构体成员的直接访…

技术书评和笔记【01】脑机接口-电路与系统 【2020版】

前言: 荷兰作者,Amir Zjajo博士,毕业于荷兰代尔夫特理工大学,方向 面向移动健康的低功耗混合型号电路与系统,以及,面向认知的神经形态电路。 ,脑机接口 - 电路与系统一书,系统介绍了,脑机接口电路与系统的实现技术,尤其,提到了量产和设计的问题,难能可贵,摘录如…

预训练语言模型transformer

预训练语言模型的学习方法有三类&#xff1a;自编码&#xff08;auto-encode, AE)、自回归&#xff08;auto regressive, AR&#xff09;&#xff0c;Encoder-Decoder结构。 决定PTM模型表现的真正原因主要有以下几点&#xff1a; 更高质量、更多数量的预训练数据增加模型容量…

CSS--Emmet 语法

Emmet语法的前身是Zen coding,它使用缩写,来提高html/css的编写速度, Vscode内部已经集成该语法. 目录 1. 快速生成HTML结构语法 1.1 快速生成HTML结构语法 2. 快速生成CSS样式语法 2.1 快速生成CSS样式语法 1. 快速生成HTML结构语法 1.1 快速生成HTML结构语法 1. 生成标…

【C++】C++ 入门 — 命名空间,输入输出,函数新特性

C 1 前言2 命名空间2.1 概念引入2.2 开始使用2.3 投入应用 3 输入与输出3.1 基础知识3.2 开始使用3.3 注意局限 4 函数新特性4.1 缺省参数4.1.1 开始使用4.1.2 注意事项 4.2 函数重载4.2.1 开始使用4.2.2 如何实现 Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读下…

仰暮计划|“老师说我其实很聪明,就是家里太穷了没条件,不然我现在也是……”

吴桂荣老人回忆录 在我外婆家的时候&#xff0c;我跟几位老奶奶坐在门口一起聊天&#xff0c;我询问她们是否能帮助我完成一份作业&#xff0c;她们笑着答应了&#xff0c;最后我选择了其中的一位老奶奶作为了解对象&#xff0c;她邀请我去家中交谈。通过了解&#xff0c;我得知…

Jmeter性能测试: 基于JDK 21 安装 Jmeter 5.6.3

目录 一、实验 1.环境 2.JDK下载 3.Jmeter下载 4.Windows安装JDK 21 5.Windows安装Jmeter 5.6.3 6.Linux安装JDK 21 7.Linux安装Jmeter 5.6.3 二、问题 1. Linux 的profile、bashrc、bash_profile文件有哪些区别 一、实验 1.环境 &#xff08;1&#xff09;主机 表…

python读取文件指定行的三种方法

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 1.行遍历实现 在python中如果要将一个文件完全加载到内存中&#xff0c;通过file.readlines()即可&#xff0c; 但是在文件占用较高时&#xff0c;我们是无法完…

springboot项目开发,使用thymeleaf前端框架的简单案例

springboot项目开发,使用thymeleaf前端框架的简单案例&#xff01;我们看一下&#xff0c;如何在springboot项目里面简单的构建一个thymeleaf的前端页面。来完成动态数据的渲染效果。 第一步&#xff0c;我们在上一小节&#xff0c;已经提前预下载了对应的组件了。 如图&#x…

2024獬豸杯完整Writeup

文章目录 手机手机基本信息- 1、IOS手机备份包是什么时候开始备份的。&#xff08;标准格式&#xff1a;2024-01-20.12:12:12)手机基本信息- 2、请分析&#xff0c;该手机共下载了几款即时通讯工具。&#xff08;标准格式&#xff1a;阿拉伯数字&#xff09;手机基本信息- 3、手…

9.OpenResty系列之10W并发实践

下图解决了上文所说的请求过多报错问题 如图所示,系统支持30W请求, 并发2W 1. /etc/sysctl.conf配置如下 vm.swappiness 0 # 表示开启SYNCookies。当出现SYN等待队列溢出时&#xff0c;启用cookies来处理&#xff0c;可防范少量SYN>攻击&#xff0c;默认为0&#xff0c;表…

雨云VPS搭建PalWorld服务器,幻兽帕鲁开服联机教程(Windows),0基础保姆级教程

雨云VPS用Windows系统搭建幻兽帕鲁私服&#xff0c;PalWorld开服联机教程&#xff0c;零基础保姆级教程&#xff0c;本教程使用一键脚本来搭建幻兽帕鲁服务端&#xff0c;并讲了如何配置游戏参数&#xff0c;如何更新服务端等。 最近这游戏挺火&#xff0c;很多人想跟朋友联机…

Ps:渐变编辑器

渐变编辑器 Gradient Editor可用于创建和编辑自定义渐变&#xff0c;它提供了详细的控制选项&#xff0c;能够精确地调整渐变的颜色、样式和效果。 提示&#xff1a; 拖动边框或边角可缩放渐变编辑器窗口。 预设 Presets 提供了大量的渐变预设。还可通过右侧按钮新建 New、导入…

台式电脑的ip地址在哪里找

在网络连接方面&#xff0c;IP地址是非常重要的信息&#xff0c;它是用于标识网络设备的唯一地址。对于台式电脑用户来说&#xff0c;了解自己设备的IP地址是非常有必要的&#xff0c;因为它可以帮助解决网络连接问题&#xff0c;进行远程访问和共享文件等功能。本文将指导读者…

go 实现暴力破解数独

一切罪恶的来源是昨晚睡前玩了一把数独&#xff0c;找虐的选了个最难的模式&#xff0c;做了一个多小时才做完&#xff0c;然后就睡不着了..........程序员不能受这委屈&#xff0c;今天咋样也得把这玩意儿破解了 破解思路&#xff08;暴力破解加深度遍历&#xff09; 把数独…

STM32 PWM驱动设计

单片机学习&#xff01; 目录 文章目录 前言 一、PWM驱动配置步骤 二、代码示例及注意事项 2.1 RCC开启时钟 2.2 配置时基单元 2.3 配置输出比较单元 2.4 配置GPIO 2.5 运行控制 三、PWM周期和占空比计算 总结 前言 PWM本质是利用面积等效原理来改变波形的有效值。 一、PWM驱动…

2024最新版Java Development Kit (JDK)安装使用指南

2024最新版Java Development Kit (JDK)安装使用指南 Installation and Configuration Guide of the latest version Java Development Kit (JDK) in 2024 By JacksonML 0. 序言 What is Java? Java is a programming language and computing platform first released by Su…

day23 其他事件(页面加载事件、页面滚动事件)

目录 页面加载事件页面/元素滚动事件页面滚动事件——获取位置 页面加载事件 加载外部资源&#xff08;如图片、外联CSS和JavaScript等&#xff09;加载完毕时触发的事件为什么使用&#xff1a; 有时候需要等页面资源全部处理完毕再做一些事老代码喜欢把script写在head中&…

【JavaScript 漫游】专栏介绍

专栏介绍 本专栏旨在记录 JavaScript 核心语法&#xff0c;作为笔者日常学习和工作中的参考手册和代码示例仓库。 内容上力求覆盖 ES5、DOM、BOM 和 ES6 规范的所有内容。对于常用且重要的知识点&#xff0c;应该详细描述并附带有大量的代码示例。对于在工作场景中很少用到的…

12.14 回退流(血干JAVA系列)

回退流 12.14 回退流【例12.67】操作回退流 12.14 回退流 表 12-23 PushbacklnputStream 类的常用方法 表12-24回退流与输入流的对应 【例12.67】操作回退流 package jiaqi;import java.io.ByteArrayInputStream; import java.io.PushbackInputStream;public class demo43…