Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【Linux】进程间通信:命名管道

【Linux】进程间通信:命名管道

作者头像
用户11029103
发布于 2025-03-14 01:30:05
发布于 2025-03-14 01:30:05
5100
代码可运行
举报
文章被收录于专栏:技术学习技术学习
运行总次数:0
代码可运行

命名管道

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

命名管道的本质是一个特殊类型的文件,但它不会存储数据,只在内存中维护一个缓冲区,进行先进先出(FIFO)的数据传输

使用 mkfifo() 或 mknod() 在文件系统中创建一个特殊文件。

  • 一个进程以写的方式打开 FIFO,并向其中写入数据。
  • 另一个进程以读的方式打开 FIFO,并从中读取数据。
  • 数据是单向流动的

命名管道可以从命令行上创建,命令行方法是使用下面这个命令

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mkfifo filename

p开头为管道文件

这里的读和写都是阻塞的,管道文件大小一直都是0,因为命名管道数据存储在内存中

命名管道也可以从程序里创建,相关函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int mkfifo(const char *filename,mode_t mode);

代码实现:首先完成管道生命周期的管理:

namedPipe.hpp文件,提供管道创建和关闭的函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#pragma once
#include<iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include<string>
#include<cerrno>
#include<cstdio>
#include<unistd.h>
using namespace std;
const string comm_path ="./myfifo";

int CreateNamedPipe(const string & path)
{
    int res =mkfifo(path.c_str(),0666);
    if(res!=0)
    {
        perror("mkfifo");
    }
    return res;
}
int RemoveNamedPipe(const string & path)
{
    int res =unlink(path.c_str());
    if(res!=0)
    {
        perror("unlink");
    }
    return res;
}

server.cc:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include"namedPipe.hpp"

int main()
{
    CreateNamedPipe(comm_path);
    RemoveNamedPipe(comm_path);
    return 0;
}

我们这里创建了两个文件,server.cc和client.cc,一定有一个文件来完成管道的创建和删除,这里生成可执行程序就是两个毫无关系的进程

这里可以对上面方法进行封装:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class NamedPipe
{
public:
    NamedPipe(const string &path) : _fifo_path(path)
    {
        int res = mkfifo(path.c_str(), 0666);
        if (res != 0)
        {
            perror("mkfifo");
        }
    }
    ~NamedPipe()
    {
        int res = unlink(_fifo_path.c_str());
        if (res != 0)
        {
            perror("unlink");
        }
    }
private:
    const string _fifo_path;
};

我的主函数直接构建对象即可:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
NamedPipe myfifo(comm_path);

管道会自动释放

这里继续在类里面添加其他功能

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const string comm_path = "./myfifo";

#define DefaultFd -1
#define Creater 1
#define User 2
#define Read O_RDONLY
#define Write O_WRONLY
class NamedPipe
{
private:
    bool OpenNamedPipe(int mode)
    {
        _fd = open(_fifo_path.c_str(), mode);
        if (_fd < 0)
            return false;
        return true;
    }

public:
    NamedPipe(const string &path, int who) : _fifo_path(path), _id(who), _fd(DefaultFd)
    {
        if (_id == Creater)
        {
            int res = mkfifo(path.c_str(), 0666);
            if (res != 0)
            {
                perror("mkfifo");
            }
        }
    }
    bool OpenForRead()
    {
        OpenNamedPipe(Read);
    }
    bool OpenForWrite()
    {
        OpenNamedPipe(Write);
    }
    ~NamedPipe()
    {
        if (_id == Creater)
        {
            int res = unlink(_fifo_path.c_str());
            if (res != 0)
            {
                perror("unlink");
            }
        }
        if(_fd!=DefaultFd) close(_fd);
    }

private:
    const string _fifo_path;
    int _id;
    int _fd;
};

隐藏打开文件的函数操作,定义宏常量Read和Write两种打开文件方式的mode,初始化传递执行者,是创建者还是使用者来决定构建的时候是否还要再进行管道文件创造

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int ReadNamedPipe(string * out)//输出型参数,输入型const& 输入输出型&
    {
        char buffer[BaseSize];
        int n = read(_fd,buffer,sizeof(buffer));
        if(n>0)
        {
            buffer[n]=0;
            *out = buffer;
        }
        
        return n;
    }
    int WriteNamedPipe(const string & in)
    {
        write(_fd,in.c_str(),in.size());
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
【Linux】进程间通信>管道&&共享内存&&消息队列&&信号量详解
vscode远程连接指南:VScode远程连接虚拟机(ubuntu系统)_vscode连接ubuntu-CSDN博客
用户10925563
2024/06/04
1930
【Linux】进程间通信>管道&&共享内存&&消息队列&&信号量详解
【Linux】进程间通信(命名管道、共享内存、消息队列、信号量)
回车之后管道不会关闭,在终端2查看可以发现他的内存大小仍然是0,当我们在管道2打印出内容后,管道就自动关闭了
用户11036582
2024/11/05
1980
【Linux】进程间通信(命名管道、共享内存、消息队列、信号量)
【Linux进程间通信】深入探索:Linux下的命名管道与System V共享内存
🔍前言:在Linux操作系统中,进程间通信(IPC)是一个至关重要的概念,它允许不同的进程之间进行数据交换和同步。随着现代操作系统的日益复杂,进程间通信的重要性也日益凸显。在众多IPC机制中,命名管道和System V共享内存无疑是两种最为常见且强大的工具
Eternity._
2024/10/10
2130
【Linux进程间通信】深入探索:Linux下的命名管道与System V共享内存
Linux命名管道及函数
管道(pipe)应用的一大局限是没有名字,只能用于具有亲缘关系进程之间的通信。而命名管道,也称FIFO,实质是一种文件类型,通过FIFO可以用于任何两个进程间的通信。
xxpcb
2020/08/04
2.7K0
论Linux进程间通信
在操作系统中,内核空间是所有进程共用的,而每个进程都拥有自己的用户空间。这种结构类似于一个公共图书馆,每个进程都有自己的阅读室”(用户空间),但它们都可以通过特定的走廊”(系统调用)访问这个图书馆(内核空间)。
小文要打代码
2025/03/04
1390
论Linux进程间通信
初识Linux · 命名管道
有了前文匿名管道的基础,我们介绍匿名管道的时候就轻松许多了,匿名管道和命名管道的区别主要是在于,匿名管道不需要文件路径,并且匿名管道常用于父子进程这种具有血缘关系的场景,使用命名管道的时候,我们常常用于的情况是两个进程毫无联系,使这两个毫无关系的进程可以进行通信。
_lazy
2024/11/19
960
初识Linux · 命名管道
【Linux】进程间通信(命名管道、共享内存、消息队列、信号量)
命名管道是通过文件路径让不同进程看到同一份资源。 命名管道可以让两个毫不相干的进程进行进程间通信。
秦jh
2024/10/29
2510
【Linux】进程间通信(命名管道、共享内存、消息队列、信号量)
进程间的通信--管道
进程之间需要协同。 例如,学校里面的各个管理层之间都是互相联系的,不能只是纵向管理。正是因为进程之间需要协同,协同的前提条件是进程之间需要通信,数据是有类别的,有的数据是通知就绪的,有些数据是单纯所传递数据,有的是控制相关的数据。
南桥
2024/07/28
860
进程间的通信--管道
【Linux】命名管道
命名管道由mkfifo创建,是一个文件,打开要用open打开 命名管道与匿名管道之间唯一的区别就是它们创建和打开的方式不同,其他基本上相同 命名管道也只能和有“血缘”的进程进行通信
s-little-monster
2025/03/04
1090
【Linux】命名管道
【Linux】 管道扩展 — 开始使用命名管道
命名管道时进程间通信的一种,那么原理也就是类似的:先让不同的进程看到同一份(操作系统)资源(“一段内存”)。
叫我龙翔
2024/05/31
1280
【Linux】 管道扩展 — 开始使用命名管道
【Linux】进程间通信——命名管道
  匿名管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。如果我们想在不相关的进程之间交换数据,可以使用命名管道来做这项工作。   在Linux系统中,命名管道(也称为FIFO,First In First Out)是一种特殊的文件类型,它允许进程间进行通信。与匿名管道不同,命名管道存在于文件系统中,并且可以被任何有适当权限的进程访问。命名管道提供了一种方法,使得不相关的进程能够通过预先定义好的路径来交换数据。
大耳朵土土垚
2024/12/04
1690
【Linux】进程间通信——命名管道
Linux进程通信--共享内存
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。
南桥
2024/07/26
1670
Linux进程通信--共享内存
【Linux进程通信】三、命名管道
​ 匿名管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。如果我们想在不相关的进程之间交换数据,可以创建和使用 FIFO 文件来做这项工作,它经常被称为命名管道。
利刃大大
2025/03/18
730
【Linux进程通信】三、命名管道
Linux进程间通信之管道
进程间通信简称IPC(Interprocess communication),进程间通信就是在不同进程之间传播或交换信息。
咬咬
2024/06/12
970
Linux进程间通信之管道
【Linux】进程间通信——命名管道
匿名管道只能用来进行进程间通信,让具有血缘关系的进程进行通信 让毫不相关的进程之间进行通信,就需要采用命名管道通信
lovevivi
2023/05/11
1.9K0
【Linux】进程间通信——命名管道
Linux进程通信之管道解析
管道是 UNIX系统 IPC的最古老的形式,所有的UNIX系统都提供此种通信。所谓的管道,也就是内核里面的一串缓存,从管道的一段写入的数据,实际上是缓存在内核中的,令一端读取,也就是从内核中读取这段数据。对于管道传输的数据是无格式的流且大小受限。对于管道来说,也分为匿名管道和命名管道,其中命名管道也被叫做 FIFO,下面则分别阐述这两种管道。
wenzid
2021/07/20
1.4K0
Linux进程通信之管道解析
【Linux】解锁管道通信和共享内存通信,探索进程间通信的海洋
进程为什么会有独立性,本质原因是:这两个进程都有自己的虚拟地址空间,但是他们的正文代码,堆,栈,共享区等被映射到了内存当中的不同的物理空间 ,所以在内存方面具有 独立性,不会互相影响
用户11316056
2024/10/16
1410
【Linux】解锁管道通信和共享内存通信,探索进程间通信的海洋
Linux:进程间通信(一.初识进程间通信、匿名管道与命名管道、共享内存)
这种双重性使得管道既具有机制的灵活性,又具有文件的可操作性。它可以在不同的进程之间建立连接,实现数据的传递和共享,同时也可以通过标准的文件操作接口进行访问和控制。
是Nero哦
2024/07/09
4690
Linux:进程间通信(一.初识进程间通信、匿名管道与命名管道、共享内存)
【Linux】深度探秘命名管道:Linux 进程通信的无声桥梁
文章链接:https://cloud.tencent.com/developer/article/2466294
Yui_
2024/11/18
1620
【Linux】深度探秘命名管道:Linux 进程通信的无声桥梁
Linux进程间通信【命名管道】
命名管道通信属于 IPC 的其中一种方式,作为管道家族,命名管道的特点就是 自带同步与互斥机制、数据单向流通,与匿名管道不同的是:命名管道有自己的名字,因此可以被没有血缘关系的进程看到,意味着命名管道可以实现毫不相干的两个独立进程间通信
北 海
2023/07/01
4280
Linux进程间通信【命名管道】
相关推荐
【Linux】进程间通信>管道&&共享内存&&消息队列&&信号量详解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验