首页 > 系统相关 >Linux下通过命名管道实现进程间通信

Linux下通过命名管道实现进程间通信

时间:2024-09-16 11:23:48浏览次数:14  
标签:创建 通信 间通信 命名 管道 Linux 进程 匿名

引入

上一篇文章介绍了 Linux 中通过pipe创建匿名管道,并实现父子进程间通信的功能;当时我就提到了 Linux 中的另一种管道通信方式——命名管道,下面就来详细介绍一下;

命名管道

什么是命名管道

命名管道(Named Pipe),也叫FIFO(First In First Out),是一种用于进程间通信(IPC)的机制。与匿名管道不同,命名管道是存在于文件系统中的特殊文件,具有持久性,可以用于不相关的进程间的数据传递;

命名管道的特点:

  • 持久性:命名管道存在于文件系统中,一旦创建,即使创建管道的进程结束,管道仍然存在,直到手动删除。
  • 半双工通信:在一个时刻数据只能单向传输,发送和接收通常需要在两个不同的进程中操作。
  • 阻塞行为:当读取端没有准备好时,写入命名管道的操作会被阻塞,反之亦然,除非使用非阻塞方式。
  • 文件系统挂载点:命名管道是通过文件系统的路径标识的,可以像普通文件一样打开、读写,但它不存储数据,只是用来传递数据。
  • 跨进程通信:命名管道支持同一主机上的不同进程之间的通信,甚至可以在父子进程之外的进程中通信。 这篇文章会详细介绍命名管道作为文件进行跨进程通信的功能;

基本操作

创建

Linux 系统中,可以使用mkfifo命令创建命名管道:

mkfifo my_pipe
# 创建一个命名管道

使用(文件属性)

之前说过,命名管道具有文件属性,所以它适用于文件的相关操作,比如:

  1. 写入进程:
echo "hello world" > my_pipe
# 向创建的命名管道中写入数据
  1. 读取进程
cat < my_pipe
# 使用 cat 读取文件内容

在这种情况下,echo 命令会把数据写入管道,而 cat 命令会从管道中读取数据。由于管道是 FIFO 的,所以数据按写入顺序被读取。

代码演示

框架搭建

下面我们搭建一个简单的模型,用于演示在命名管道下进程间的通信:

  1. 首先我们需要了解命名管道可以用于没有相关性的进程之间的通信,所以我们创建两个可执行文件,用于模拟两个不同进程;
  2. 随后调用系统函数writeopenread等对信息写入、读取等工作;
  3. 对于mkfifo函数,可以查到它的接口:
int mkfifo(const char* pathname, mode_t mode);
// pathname,即路径名称,用于指定管道文件的创建位置
// mode,模式选项,这里指文件的权限信息

所以我们需要一个路径名称和权限选项(八进制); 综合上述说明,我们就得到了一个简易的程序框架,下面就是代码实现;

代码实现

这个代码实现和上一篇文章的匿名管道类似,这里不再贴出代码,具体代码细节可以访问我的GitHub主页,位于pipe文件夹下;

匿名和命名管道之间的区别

最后我们再来总结一下这两者之间的区别,便于大家更好的理解管道的内容:

  1. 命名方式
  • 匿名管道:没有名字,存在于内存中,由创建它的进程通过文件描述符来引用。匿名管道只能用于相关的进程之间(例如,父子进程)。
  • 命名管道:有名字,存在于文件系统中。不同的进程可以通过路径名来引用它,可以用于不相关的进程之间的通信。
  1. 创建方式
  • 匿名管道:在 C 语言中,使用 pipe() 系统调用创建匿名管道,它会返回两个文件描述符,一个用于读,一个用于写。例如:
int pipefd[2];
pipe(pipefd); // 创建匿名管道
  • 命名管道:在 C 语言中,可以通过 mkfifo() 系统调用创建命名管道,它会在文件系统中创建一个特殊的 FIFO 文件。例如:
mkfifo("/tmp/mypipe", 0666); // 创建命名管道
  1. 通信进程的关系
  • 匿名管道:仅限于相关进程之间的通信,如父进程和子进程,因为它们继承了同样的文件描述符。匿名管道不适合不相关的进程之间进行通信。
  • 命名管道:可以用于不相关进程之间的通信,因为它通过文件系统路径命名,任何有权限的进程都可以通过路径名打开这个管道进行通信。
  1. 生命周期
  • 匿名管道:管道的生命周期与进程相同,一旦创建管道的进程退出,管道也会销毁。
  • 命名管道:命名管道的生命周期与文件系统中的文件类似,管道文件在手动删除之前会一直存在,即使创建它的进程已经退出。
  1. 可见性
  • 匿名管道:对用户和文件系统不可见,完全存在于内存中。
  • 命名管道:在文件系统中可见,可以通过命令 ls 等查看,也可以通过路径进行操作。
  1. 典型使用场景
  • 匿名管道:用于父子进程或兄弟进程间的简单通信,通常是在进程创建时立即建立通信通道。常用于短期通信,通常不会持久存在。
  • 命名管道:用于需要在不相关进程间进行通信的场景,尤其是当进程可能独立运行,彼此需要通过一个预定义的管道进行通信时。
  1. 跨用户或网络通信
  • 匿名管道:仅限于在同一台计算机上的进程通信,且必须是直接相关的进程(父子或兄弟进程)。
  • 命名管道:尽管主要用于本地进程间通信,但可以通过网络文件系统(NFS)等实现跨网络的间接通信,但并不常用于此类场景。

区别总结表:

特性 匿名管道 命名管道
命名方式 无名称,通过文件描述符标识 有名称,通过文件系统路径标识
创建方式 pipe() 系统调用 mkfifo() 系统调用
使用进程 父子进程、兄弟进程 不相关的进程都可以使用
通信范围 仅限相关进程 不相关的进程可通过文件路径通信
生命周期 与创建进程相同,进程结束即销毁 在文件系统中持续存在,直到手动删除
可见性 不可见,完全在内存中 可见,在文件系统中
典型场景 父子进程间的简单通信 不相关进程间的长时间通信

标签:创建,通信,间通信,命名,管道,Linux,进程,匿名
From: https://blog.51cto.com/u_16271511/12030523

相关文章

  • 5.linux磁盘管理
     目录一.基本分区1.磁盘简介2.管理磁盘a.查看磁盘信息b.创建分区-MBRc.创建文件系统-格式化d.挂载mounte.查看挂载信息3.扩展二.逻辑卷LVM1.创建LVM2.VG管理3.LV扩容三.交换分区管理Swap1.简介2.查看当前的交换分区3.增加交换分区4.扩展点一.基本......
  • Linux内存管理知识-一篇文章了解堆和栈区别(进阶篇)
    前面已经介绍过,栈是由编译器在需要时分配的,不需要时自动清除的变量存储区。里面的变量通常是局部变量、函数参数等。堆是由malloc()函数分配的内存块,内存释放由程序员手动控制,在C语言为free函数完成。栈和堆的主要区别有以下几点:(1)管理方式不同栈编译器自动管理,无需程序员手......
  • Kali Linux 2024.3 发布下载 - 领先的渗透测试发行版
    KaliLinux2024.3发布(Multipletransitions)-领先的渗透测试发行版ThemostadvancedPenetrationTestingDistribution请访问原文链接:https://sysin.org/blog/kali-linux/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgKaliLinux2024.3已经可以下载,发行......
  • Linux查看服务器日志
    一、tail这个是我最常用的一种查看方式用法如下:tail-n10test.log查询日志尾部最后10行的日志;tail-n+10test.log查询10行之后的所有日志;tail-fn10test.log循环实时查看最后1000行记录(最常用的)一般还会配合着grep用,(实时抓包)例如:tai......
  • linux下安装部署Maven
    目录版本对应关系安装maven配置maven验证版本对应关系不同版本下载地址:https://archive.apache.org/dist/maven/Maven与JDK版本的对应关系主要取决于Maven的版本和所需的Java版本。以下是具体的对应关系:Maven2.0.11及以下版本支持JDK1.3和JDK1.4。Maven2.0.11及以上版......
  • linux下安装部署Node
    目录node下载二进制包验证node由于管理后台要求构建工具Node>=12,所以我们就选用最接近此版本的Node-v12.18.3TLS(稳定版本)下载二进制包#!/bin/bashyuminstallgzip-y[-d/data/setup/]||mkdir-p/data/setup/[-d/data/prog/]||mkdir-p/data/prog/......
  • linux下安装部署jenkins
    目录环境准备jdk安装安装依赖安装jenkins启动jenkins查看初始密码更换源汉化环境准备jdk安装1.8版本安装#!/bin/bash[-d/data/setup/]||mkdir-p/data/setup/[-d/data/prog/]||mkdir-p/data/prog/cd/data/setup/[-f/data/setup/jdk-8u271-linux-x64.......
  • Linux
    1.‌cd‌:用于切换当前工作目录。例如,cd/切换到根目录,cd..切换到上一级目录。2.‌ls‌:列出当前目录下的文件和子目录。例如,ls-l以详细格式显示文件和目录的权限、所有者、大小等信息。3.‌pwd‌:显示当前工作目录的路径。‌4.mkdir‌:创建新的目录。例如,mkdirnewdir创建一......
  • linux下部署安装gitlab
    目录安装依赖安装gitlab更改配置初始化启动gitlab设置密码汉化安装依赖#gitlab安装echogitlab>/etc/hostnamehostnamegitlabyuminstall-ycurlpolicycoreutilsopenssh-serveropenssh-clientspolicycoreutils-pythonyuminstall-ypostfix安装gitlabwgeth......
  • 详解 Linux 系统下的进程(下)
    目录一.进程控制1.进程创建a.Linux系统中,如何创建一个进程?b.进程创建成功后,Linux底层会为其做些什么?2.进程终止a.什么是进程终止?b.进程终止的方法有哪些?c.exit 与_exit的区别3.进程等待a.什么进程等待? b.为什么要进程等待?c.如何进行进程等待?①wait②waitp......