【Linux】学习记录_10_管道

embedded/2024/11/13 9:41:30/

10 管道

数据可以从一个进程流向另一个进程

10.1 匿名管道PIPE

匿名管道有以下的特征:

  • 没有名字,因此不能使用open()函数打开,但可以使用close()函数关闭。

  • 只提供单向通信(半双工),也就是说,两个进程都能访问这个文件,假设进程1往文件内写东西, 那么进程2就只能读取文件的内容。

  • 只能用于具有血缘关系的进程间通信,通常用于父子进程建通信 。

  • 管道是基于字节流来通信的。

  • 依赖于文件系统,它的生命周期随进程的结束而结束。

  • 写入操作不具有原子性,因此只能用于一对一的简单通信情形。

  • 管道也可以看成是一种特殊的文件,对于它的读写也可以使用普通的read()和write()等函数。 但是它又不是普通的文件,并不属于其他任何文件系统,并且只存在于内核的内存空间中, 因此不能使用lseek()来定位。

10.2 命名管道FIFO

命名管道有以下的特征:

  • 有名字,存储于普通文件系统之中。

  • 任何具有相应权限的进程都可以使用 open()来获取命名管道的文件描述符。

  • 跟普通文件一样:使用统一的 read()/write()来读写。

  • 跟普通文件不同:不能使用 lseek()来定位,原因是数据存储于内存中。

  • 具有写入原子性,支持多写者同时进行写操作而数据不会互相践踏。

  • 遵循先进先出(First In First Out)原则,最先被写入 FIFO的数据,最先被读出来。

10.3 pipe()函数

int pipe(int pipefd[2]);

数组pipefd是用于返回两个引用管道末端的文件描述符, pipefd[0] 指管道的读取端,pipefd[1]指向管道的写端 , 向管道的写入端写入数据将会由内核缓冲,即写入内存中,直到从管道的读取端读取数据为止, 而且数据遵循先进先出原则。pipe()函数还会返回一个int类型的变量, 如果为0则表示创建匿名管道成功,如果为-1则表示创建失败,并且设置errno。

匿名管道创建成功以后,创建该匿名管道的进程(父进程)同时掌握着管道的读取端和写入端, 但是想要父子进程间有数据交互,则需要以下操作:

  • 父进程调用pipe()函数创建匿名管道,得到两个文件描述符pipefd[0]、pipefd[1], 分别指向管道的读取端和写入端。

  • 父进程调用fork()函数启动(创建)一个子进程, 那么子进程将从父进程中继承这两个文件描述符pipefd[0]、pipefd[1], 它们指向同一匿名管道的读取端与写入端。

  • 由于匿名管道是利用环形队列实现的,数据将从写入端流入管道,从读取端流出,这样子就实现了进程间通信, 但是这个匿名管道此时有两个读取端与两个写入端。

    fork()后子进程继承父进程文件描述符

  • 如果想要从父进程将数据传递给子进程,则父进程需要关闭读取端,子进程关闭写入端

    数据从父进程流向子进程

  • 如果想要从子进程将数据传递给父进程,则父进程需要关闭写入端,子进程关闭读取端

    数据从子进程流向父进程

  • 当不需要管道的时候,就在进程中将未关闭的一端关闭即可

10.4 fifo()函数

int mkfifo(const char * pathname,mode_t mode);

mkfifo()会根据参数pathname建立特殊的FIFO文件,而参数mode为该文件的模式与权限。

mkfifo()创建的FIFO文件其他进程都可以进行读写操作,可以使用读写一般文件的方式操作它, 如open,read,write,close等。

mode模式及权限参数说明:

  • O_RDONLY:读管道。

  • O_WRONLY:写管道。

  • O_RDWR:读写管道。

  • O_NONBLOCK:非阻塞。

  • O_CREAT:如果该文件不存在,那么就创建一个新的文件,用第三个参数为其设置权限

  • O_EXCL:如果使用O_CREAT时文件存在,那么可返回错误消息。可测试文件是否存在。

函数返回值说明如下:

  • 0:成功

  • EACCESS:参数 filename 所指定的目录路径无可执行的权限。

  • EEXIST:参数 filename 所指定的文件已存在。

  • ENAMETOOLONG:参数 filename 的路径名称太长。

  • ENOENT:参数 filename 包含的目录不存在。

  • ENOSPC:文件系统的剩余空间不足。

  • ENOTDIR:参数 filename 路径中的目录存在但却非真正的目录。

  • EROFS:参数 filename 指定的文件存在于只读文件系统内。

使用FIFO的过程中,当一个进程对管道进行读操作时:

  • 若该管道是阻塞类型,且当前FIFO内没有数据,则对读进程将一直阻塞到有数据写入。

  • 若该管道是非阻塞类型,不论FIFO内是否有数据,读进程都会立即执行读操作。 即如果FIFO内没有数据,读函数将立刻返回 0。

使用FIFO的过程中,当一个进程对管道进行写操作时:

  • 若该管道是阻塞类型,则写操作将一直阻塞到数据可以被写入。

  • 若该管道是非阻塞类型而不能写入全部数据,则写操作进行部分写入或者调用失败


http://www.ppmy.cn/embedded/11404.html

相关文章

海外住宅IP如何助力国外问卷调查?

在数字化时代,国外问卷调查不仅是了解市场需求的重要手段,还成为了一项能够赚取额外收入的方式。随着全球范围内消费者行为的多样化,各类企业和机构越来越需要了解不同地区的用户观点和偏好,以优化产品和服务。 一、国外问卷调查…

Pytorch:张量的梯度计算

目录 一、自动微分简单介绍1、基本原理2、梯度计算过程3、示例:基于 PyTorch 的自动微分a.示例详解b.梯度计算过程c.可视化计算图 4、总结 二、为什么要计算损失,为何权重更新是对的?1、梯度下降数学原理2、梯度上升 三、在模型中使用自动微分…

overleaf如何使用中文(超简单)

LaTeX默认都是不支持中文的,有时候我们想输入中文。 1、编译器配置为XeLaTeX 菜单-编译器-XeLaTeX 2、代码开头添加宏包 \usepackage[UTF8]{ctex}

Excel中将单元格格式改成文本后,为何要双击数字才会改变?

将大批量的数值型数字转换成文本型数字,当然不能一个一个的去双击做转换了。以下说说有哪个可以将数值型数字转换成文本型数字的方法。 一、转换方法 方法1.数据分列功能 选中数据后,点击数据选项卡,分列, 分列向导的第一步和…

关于Qt主窗口的菜单部件

前言 在介绍主窗口的两大部件之前,我们要先知道关于主窗口的一些知识。 主窗口 一个主窗口可以没有菜单条、工具条、状态条,但必须设置中心部件。在 Q 生成的 C头文件 ui_mainwindow.h 代码中,我们可以看到以下代码: centralWidget new Qwidget(MainWi…

美国签证证件照规格要求(51mm*51mm)

美国签证证件照规格要求(51mm*51mm)

中华环保联合会获得国家“绿色制造体系” 第三方评价机构资格

近日,中华环保联合会成功获得工业和信息化部“绿色制造体系”第三方评价机构资格,可为企业、园区及相关机构提供全面的绿色制造体系评价服务,包括绿色工厂、绿色园区、绿色供应链等方面。 “绿色制造体系建设”是由工业和信息化部负责统筹推进…

Docker容器搭建Hadoop集群(hadoop-3.1.3)

Docker容器环境下搭建Hadoop集群(完全分布式) hadoop版本为hadoop-3.1.3 (1)安装额外的速度较快的镜像库 yum install -y epel-release (2)安装同步工具,方便在多台服务器上进行文件的传输 …