【Linux】命令管道

一、命名管道的介绍

之前的管道博客中介绍的是匿名管道,这个管道的应用的一个限制就是只能在具有公共祖先(具有亲缘关系)的进程间通信。

如果我们不想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,他经常被称为命名管道。

命名管道是一种特殊类型的文件。

二、有关于命名管道的函数接口

2.1 mkfifo函数

函数原型

函数参数

  • pathname:这是一个字符串,表示要创建的FIFO文件的路径。
  • mode(可选):这个是一个整数,表示新创建的FIFO的权限模式,默认值通常是0666,表示读写权。

函数功能

mkfifo函数通过提供的路径创建一个命名管道,允许不同进程之间进行通信。命名官大是一种特殊类型的文件,可以被多个进程打开,用于数据传输。

函数的返回值

  • 成功 : 返回 true
  • 失败 : 返回 false,并且可以通过 error_get_last() 函数获取详细的错误信息。

2.2 unlink函数

函数原型

函数参数

  • filename:这是一个字符串,表示要删除的文件的路径

函数功能

unlink函数通过提供的文件名删除指定的文件。如果文件成功删除,则返回true;如果文件不存在或者发生了其他错误,则返回false。

函数的返回值

  • 成功 : 返回 true
  • 失败 : 返回 false,并且可以通过 error_get_last() 函数获取详细的错误信息。

三、匿名管道和命名管道的区别

  • 匿名管道由pipe函数创建并打开
  • 命名管道由mkfifo函数创建,打开该文件使用open
  • FIFO(命名管道)与PIPE(匿名管道)之间唯一的区别在于他们创建和打开的方式不同,一旦这些工作完成了,他们具有相同的语义

四、命名管道的打开规则

如果当前打开操作是为读而打开FIFO时:

  • O_NONBLOCK disable 阻塞直到有相应进程为读而打开该FIFO
  • O_NONBLOCK enable 立刻返回成功

如果当前打开操作是为写而打开FIFO时:

  • O_NONBLOCK disable 阻塞直到有相应进程为写而打开该FIFO
  • O_NONBLOCK enable 立刻返回失败,错误码为ENXIO

五、利用命名管道实现客户端和服务端的通信

我们先将这个命名管道封装一下,然后进行一系列操作,就是将构造函数和析构函数进行封装:

cpp 复制代码
#define mode 0644
#define Path "./fifo"

class Fifo
{
publlic:    
    Fifo(const std::string &path)
    {
        umask(0); // 将系统中的掩码进行改变
        int n = mkfifo(_path.c_str(), mode);
        if(n == 0)
        {
            std::cout << "mkfifo success..." << std::endl;
        }
        else
        {
            std::cerr << "mkfifo failed, errno: " << errno << ", errstring: " << strerrno(errno) << std::endl; 
        }
    }

    ~Fifo()
    {
        int n = unlink(_path.c_str());
        if (n == 0)
        {
            std::cout << "unlink success ..." << std::endl;
        }
        else
        {
            cerr << "unlink failed, errno: " << errno << ", errstring: " << strerror(errno) << endl;
        }
    }

private:    
    std::string _path; // 文件路径 + 文件名字
};

服务端创建FIFO管道,然后打开文件进读取管道的方式

cpp 复制代码
// 1. 创建出命名管道
// 2. 打开所创建的命名管道
// 3. 服务端进行读取数据
// 4. 服务端关闭文件

客户端打开管道,然后进行写入管道的方式

cpp 复制代码
// 1. 客户端直接以写的方式打开命名管道
// 2. 客户端直接写入管道中
// 3. 客户端关闭命名管道

重点是:让两个需要通信的进程看到同一个共享空间

相关推荐
一枝小雨2 分钟前
【OJ】C++ vector类OJ题
数据结构·c++·算法·leetcode·oj题
一枝小雨2 分钟前
【C++】Vector完全指南:动态数组高效使用
开发语言·c++·笔记·vector·学习笔记·std库
大白的编程日记.18 分钟前
【Linux学习笔记】信号的深入理解之软件条件产生信号
linux·笔记·学习
群联云防护小杜24 分钟前
服务器异常磁盘写排查手册 · 已删除文件句柄篇
运维·服务器·nginx·开源·lua
buyutang_27 分钟前
C/C++ Linux系统编程:线程控制详解,从线程创建到线程终止
linux·c语言·c++·学习
liliangcsdn33 分钟前
结合prompt分析NodeRAG的build过程
java·服务器·人工智能·数据分析·知识图谱
云的牧人40 分钟前
Ubuntu 22 redis集群搭建
linux·运维·ubuntu
siriuuus1 小时前
Linux 磁盘扩容及分区相关操作实践
linux·运维·服务器
Qiang_san1 小时前
GNU Make | C/C++项目自动构建入门
c语言·c++·gnu
To_再飞行1 小时前
K8s 存储配置资源
linux·云原生·容器·kubernetes