Linux 管道

本文详细介绍了Unix/Linux系统中的管道,包括匿名管道的单向通信、父子进程间的通信机制,以及命名管道的概念、创建方法、特性与用途。对比了两者在持久性、通信范围和权限控制方面的差异。
摘要由CSDN通过智能技术生成

目录

一、认识管道

 二、匿名管道

pipe函数

用法:

pipefd:

匿名管道通信:

 三、命名管道

概念:

创建:

特性:

用途:

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

命名:

持久性:

进程间通信:

创建方式:

权限控制:


一、认识管道

将一个进程连接到另一个进程的数据量,我们称它为管道

 在图片中who和wc是两个命令,运行后产生两个进程,who进程通过标准输出将数据送到管道中,wc进程再通过标准输入在管道中读取,数据传输完成。

who命令是查看当前云服务器的登陆用户,wc是统计当前行数

 二、匿名管道

匿名管道是一种简单而有效的进程间通信方式,特别适用于父子进程之间或者相关进程之间的数据传输。

使用匿名管道实现父子进程间通信的原理就是,让两个父子进程先看到同一份被打开的文件资源,然后父子进程就可以对该文件进行写入或是读取操作,进而实现父子进程间通信。

 注意:

  • 管道方向:匿名管道是单向的,可以用于父子进程或兄弟进程之间的通信。如果需要双向通信,需要创建两个管道。
  • 管道大小:匿名管道有固定的缓冲区大小。在写入管道时,如果写入的数据超过管道的容量,写入操作可能会阻塞或失败。因此,要确保在读取管道之前,已经将所有数据写入管道。
  • 阻塞操作:管道的读取和写入操作默认是阻塞的,即如果没有可读数据或管道已满,写入和读取操作将阻塞进程。要避免阻塞,可以使用非阻塞的I/O操作或将管道设置为非阻塞模式。
  • 进程间同步:如果多个进程同时读取或写入管道,可能会出现竞态条件。可以使用同步机制(如互斥锁或信号量)来确保进程之间的正确同步。
  • 管道的生命周期:匿名管道在父进程和子进程之间共享,但在父进程终止后,子进程仍然可以继续使用管道。确保在不再需要管道时正确关闭它们,以避免资源泄漏。

pipe函数

pipe()函数是一个在 Unix/Linux 系统中用于创建管道的系统调用。它创建一个管道,用于在两个相关的进程之间进行通信,其中一个进程作为管道的写入端,另一个进程作为管道的读取端。

用法:

#include <unistd.h>

int pipe(int pipefd[2]);

pipefd:

在函数原型中,pipefd是一个整型数组,它有两个元素pipefd[0]表示管道的读取端、pipefd[1]表示管道的写入端。

  • pipefd[0]:读取端是一个打开的文件描述符,用于从管道中读取数据。当管道中有数据可读时,对该文件描述符的读取操作将成功,否则读取操作将阻塞
  • pipefd[1]:写入端是一个打开的文件描述符,用于向管道中写入数据。当管道的写入缓冲区未满时,对该文件描述符的写入操作将成功,否则写入操作将阻塞

(读取端):当进程从管道读取数据时,应该使用这个文件描述符。读取端是一个打开的文件描述符,用于从管道中读取数据。当管道中有数据可读时,对该文件描述符的读取操作将成功,否则读取操作将阻塞,直到有数据可读或者管道关闭。


匿名管道通信:

在创建匿名管道实现父子间通信需要fork()和pipe()搭配使用

1.父进程使用pipe创建管道

 2.父进程创建子进程

 

父进程关闭写端,子进程关闭读端 

  • 管道只能够进行单向通信,因此当父进程创建完子进程后,需要确认父子进程谁读谁写,然后关闭相应的读写端。
  • 从管道写端写入的数据会被存到内核缓冲,直到从管道的读端被读取。 

 三、命名管道

  1. 概念

    • 命名管道是一种特殊类型的文件,它允许不相关的进程之间进行通信。
    • 与匿名管道不同,命名管道是由文件系统中的路径名标识的。
  2. 创建

    • 可以使用mkfifo命令在文件系统中创建命名管道。
    • 也可以使用mkfifo()系统调用在程序中创建命名管道。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main() {
    char *fifo_path = "/tmp/myfifo"; // 命名管道的路径名

    // 使用 mkfifo() 函数创建命名管道
    if (mkfifo(fifo_path, 0666) == -1) {
        perror("mkfifo");
        exit(EXIT_FAILURE);
    }

    printf("Named pipe created successfully at %s\n", fifo_path);

    return 0;
}

  1. 特性

    • 命名管道在文件系统中以文件的形式存在,但其行为类似于管道。
    • 命名管道具有阻塞特性,当写入数据时,如果没有进程读取数据,则写入进程会被阻塞。
    • 命名管道就是一种特殊类型的文件,两个进程通过命名管道的文件名打开同一个管道文件。
    • 命名管道可以像普通文件一样设置权限,以控制哪些进程可以访问它。
    • 进程通过向命名管道写入数据,然后由另一个进程从管道读取数据来进行通信。
    • 多个进程可以同时向命名管道写入数据,但只有一个进程可以读取数据。
    • 命名管道遵循文件系统的生命周期,可以通过删除其路径名来销毁管道。
  2. 用途

    • 命名管道常用于同一主机上的不同进程之间的通信,特别是当这些进程无法通过常规IPC(Inter-Process Communication)机制通信时。
    • 它们可以在shell脚本中用作简单的IPC机制,允许不同的shell命令之间进行通信
    • 命名管道通常用于本地进程间通信,因此不适用于远程进程通信

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

  1. 命名

    • 命名管道有一个在文件系统中的路径名,可以通过文件系统访问和识别。
    • 匿名管道没有在文件系统中的路径名,只能在创建它的进程内部使用。
  2. 持久性

    • 命名管道是持久的,它们在文件系统中存在,直到被显式删除。
    • 匿名管道是临时的,它们只存在于创建它们的进程的生命周期中,进程结束时管道会自动被销毁。
  3. 进程间通信

    • 命名管道允许不相关的进程之间进行通信,因为它们可以在文件系统中识别。
    • 匿名管道只适用于具有父子关系的相关进程之间的通信,因为它们是通过pipe()系统调用创建的,并且没有在文件系统中的路径名。
  4. 创建方式

    • 命名管道可以使用mkfifo命令或mkfifo()系统调用在文件系统中创建。
    • 匿名管道可以使用pipe()系统调用在内存中创建,但它们不在文件系统中可见。
  5. 权限控制

    • 命名管道可以像普通文件一样设置权限,以控制哪些进程可以访问它。
    • 匿名管道没有权限控制,只能由创建它的进程和其子进程访问。

        总的来说,命名管道和匿名管道都是进程间通信的方式,但它们的持久性、适用范围和创建方式有所不同。如果需要在不相关的进程之间进行通信,并且需要持久性,则可以选择命名管道;如果只需要在相关进程之间进行临时通信,则可以选择匿名管道。

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值