linux进程通信———有名管道FIFO

本文介绍了Linux中的有名管道FIFO,这是一种允许无亲缘关系进程间通信的方式。FIFO通过文件系统中的路径名关联,支持无血缘关系进程的读写操作。文章详细讲解了FIFO的创建、打开规则、读写数据的细节,并给出了无亲缘关系服务器与客户端的代码实例,最后探讨了FIFO的内核实现。
摘要由CSDN通过智能技术生成

linux进程通信———有名管道FIFO

引言:无名管道的一个重大限制是它没有名字,通信范围限定在具有血缘关系的进程间。有名管道以FIFO文件形式存在于文件系统中。这样即使与FIFO创建进程不存在血缘关系的进程,只要访问该路径,就能够通过FIFO通信。本篇笔记包括FIFO介绍、代码实例、内核实现。



一、FIFO简介

1.1、“有名”管道:

  FIFO指代先进先出(first in, first out),Unix中的FIFO类似于管道。它是一个单向(半双工的数据流)。不同于管道的是,每个FIFO有一个路径名与之对之关联,从而允许无亲缘关系的进程访问同一个FIFO,进行通信。FIFO也称为有名管道(named pipe)。

这里写图片描述
图1、pipe与fifo对比,详情参考man 7 pipe

1.2、创建:

  FIFO由mkfifo()函数创建,函数原型为:

int mkfifo(const char *pathname, mode_t mode)

  • const char *pathname:是一个普通的unix路径名,它是该FIFO的名字。
  • **mode:**mode参数指定FIFO权限位,它是S_IRUSER(属主读)、S_IWUSR(属主写)、S_IRGRP(组成员读)、S_IWGRP(组成员写)、S_IROTH(其他用户读)、S_IWOTH(其他用户写)这六个常值按位或组成的。

这里写图片描述
图2、mkfifo函数man手册

  mkfifo函数已隐含制定O_CREAT | O_EXCL,也就是说,它要么创建一个新的FIFO,要么返回一个EEXIST错误(所指定名字的FIFO已经存在)。如果不希望创建一个新的FIFO,那么就改为调用open而不是mkfifo。要打开一个已经存在或希望创建一个新的FIFO,应先调用mkfifo,再检查它是否返回EEXIST错误,若返回该错误则改为调用open。

1.3、FIFO的打开规则:

1)、如果当前打开操作是为读而打开FIFO时,若已经有相应进程为写而打开该FIFO,则当前打开操作将成功返回;否则,可能阻塞直到有相应进程为写而打开该FIFO(当前打开操作设置了阻塞标志);或者,成功返回(当前打开操作没有设置阻塞标志)。
2)、如果当前打开操作是为写而打开FIFO时,如果已经有相应进程为读而打开该FIFO,则当前打开操作将成功返回;否则,可能阻塞直到有相应进程为读而打开该FIFO(当前打开操作设置了阻塞标志);或者,返回ENXIO错误(当前打开操作没有设置阻塞标志)。

总之,一旦设置了阻塞标志,调用mkfifo建立好之后,那么管道的两端读写必须分别打开,有任何一方未打开,则在调用open的时候就阻塞。对管道或者FIFO的write总是向末尾添加数据,对它们的read总是从开头返回数据,对管道或者FIFO调用lseek,返回ESPIPE错误。

这里写图片描述
图3、管道内数据流动

1.4、FIFO中读取数据:

  如果一个进程为了从FIFO中读取数据而阻塞打开FIFO,那么称该进程内的读操作为设置了阻塞标志的读操作。并且有进程写打开FIFO,且当前FIFO内没有数据,即此时管道的两端都建立好了,但是写端还没有写数据

1)、则对于设置了阻塞标志的读操作来说,将一直阻塞(就是block住了,等待数据。它并不消耗CPU资源,这种进程的同步方式对CPU而言是非常有效率的。)
2)、对于没有设置阻塞标志读操作来说则返回-1,当前errno值为EAGAIN,提醒以后再试。

  对于设置了阻塞标志的读操作来说,造成阻塞的原因有两种

1)、FIFO内有数据,但有其它进程在读这些数据(对于各个读进程而言,这根有名管道是临界资源,大家得互相谦让,不能一起用。)
2)、FIFO内没有数据。解阻塞的原因则是FIFO中有新的数据写入,读操作不会因为FIFO中的字节数小于请求读的字节数而阻塞,此时,读操作会返回FIFO中现有的数据量。

需要注意的一点是:读打开的阻塞标志只对本进程第一个读操作施加作用,如果本进程内有多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值