FIFO

2015-02-21 16:09:14   最后更新: 2015-02-21 17:08:05   访问数量:1290




FIFO 有时被称为“命名管道”

管道只能由相关进程使用,这些相关进程必须有共同的祖先进程,但通过 FIFO,即便是不相关的进程也可以相互通信

函数原型

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

 

定义于 sys/stat.h 中

调用成功返回 0,否则返回 -1

 

参数说明

  • pathname

FIFO 事实上是一种文件类型,可以通过 stat 函数与 S_ISFIFO 宏对此进行检测

FIFO 的创建与 open 创建文件的过程非常类似,而事实上,用于 FIFO 通信的文件也存在于文件系统中

pathname 参数指定了该路径

 

  • mode

该参数与 open 函数的对应参数取值相同

mode 参数取值
参数是否必须意义
O_RDONLY只读
O_WRONLY只写
O_RDWR读写
O_APPEND 每次写时都追加到文件尾
O_CREAT 如果文件不存在,则创建文件
O_EXCL 测试文件是否存在,如不存在则创建文件,不能和O_CREAT同时指定
O_TRUNC 如果文件存在并被成功打开,并且可以写入,则先清空文件
O_NOCTTY 如果pathname参数指定的是一个终端设备,则不将该设备分配为此进程的控制终端
O_NONBLOCK 如果pathname参数指定的是一个FIFO、一个块特殊文件或一个字符特殊文件,则将本次打开操作和后续IO操作设置为非阻塞模式

mode 参数使用表中宏的一个或多个的逻辑或,三个必须的宏必选其一

 

如果没有设定 O_NONBLOCK 标志,则只读 open 会一直阻塞,直到某个进程为写而打开此 FIFO,只写 open 会一直阻塞知道某个进程为读而打开此 FIFO

如果设定了 O_NONBLOCK 标志,则 open 操作会立即返回,如果没有进程已经为读,则只写 open 将出错返回 -1,errno 同时被置为 ENXIO

 

一旦使用 mkfifo 创建了一个 FIFO,就可以使用 open 打开它,如同一般的文件一样,使用 IO 函数(close、read、write、unlink等)进行操作

类似于管道,如果用 write 写一个尚无进程为读而打开的 FIFO,则产生信号 SIGPIPE

若某个 FIFO 的最后一个写进程关闭了该 FIFO,则将为该 FIFO 的读进程产生一个文件结束标志

 

与管道一样,PIPE_BUF 说明了可被写入 FIFO 的最大数据量

 

FIFO 有下面两个用途:

  1. 由 shell 命令使用一遍将数据从一条管道线传送到另一条,为此无需创建中间临时文件
  2. 用于 client-server 进程应用程序中,以在 client 和 server 间传递数据

 

用 FIFO 复制输出流

考虑一个实际中的问题,进程 1 读入一个文件,并通过标准输出返回处理结果,进程 2 和进程 3 都需要接收进程 1 的处理结果

那么,使用下面的命令可以避免创建临时文件

mkfifo fifo1 prog3 < fifo1 & prog1 < infile | tee fifo1 | prog2

 

命令 tee 将标准输出复制到指定的文件(fifo1)中

 

在这一过程中,首先创建了一个 FIFO,然后启动 prog3 从 FIFO 中读取数据,然后 prog1 的标准输出被 tee 发送到 FIFO 和 prog2

 

client - server 使用 FIFO 进行通信

下图展示了一个服务器模型

 

 

这种安排虽然可以工作,但是服务器并不能判断一个客户进程是否崩溃中止

而同时,服务器必须捕捉 SIGPIPE 信号

 






读书笔记      技术帖      unp      unix网络编程      龙潭书斋      服务器      apue      unix环境高级编程      进程间通信      ipc      server      fifo      mkfifo      tee      client     


京ICP备15018585号