一、概念
管道作为进程间通信的最古老方式,它的缺点是没有名字,因此管道仅仅能用在有亲缘关系的父子进程之间。对于无亲缘关系的进程间。无法用管道进行通信。
FIFO能够完成无亲缘关系的进程间的通信。
FIFO也被称为命名管道。它是一种特殊类型的文件。在文件系统中以文件名称的形式存在,但它的行为却和上面提到的管道类似。
二、创建FIFO
创建命名管道有两种方法:
1、在命令行上运行命令:mkfifo filename 来创建FIFO。
2、使用mkfifo函数创建FIFO。
include <sys/types.h>
#include <sys/stat.h>
int mkfifo (const char* pathname, mode_t mode) ;
其中pathname是一个普通的Unix路径名,它是该FIFO的名字。
mode参数指定文件权限位,类似于open的第二个参数
三、注意事项
3.1、创建与打开
- mkfifo函数仅仅是创建FIFO,要想打开它,还必须使用open函数。
- 创建fifo的过程中是隐含了O_CREAT| O_EXCL标志的,也就是说它要么创建一个新的FIFO,要么返回一个EEXIST错误。
- 要打开一个已存在的FIFO或创建一个新的FIFO,应先调用mkfifo,再检查它是否返回EEXIST错误,若返回该错误则改为调用open。
- FIFO不能打来来既读又写,由于它是半双工的。
3.2、阻塞
当打开(open)一个FIFO时,非阻塞标志产生下列影响:
-
一般情况,若当前尚无任何进程打开FIFO来写,那么打开该FIFO读的进程将阻塞。同样,只写open要阻塞到某个其他进程为读而打开它。
-
如果指定了O_NONBLOCK,则只读open立即返回。但是,若当前尚无任何进程打开FIFO来读,那么只写open将出错返回-1。
类似于管道,若用write写一个尚无进程为读而打开的FIFO,则产生信号SIGPIPE。若用read读一个已关闭的FIFO,则会读到一个文件结束标志。
四、FIFO与管道的差别
-
创建并打开一个管道仅仅须要调用pipe。创建并打开一个FIFO则须要调用mkfifo后再调用open。
-
管道在全部进程终于都关闭之后自己主动消失,FIFO的名字则仅仅有调用unlink才从文件系统中删除。
管道与FIFO都有系统加在他们上面的限制:
-
OPEN_MAX 一个进程在随意时刻打开的最大描写叙述符数。
-
PIPE_BUF 可原子地写一个管道或FIFO的最大数据量。
五、FIFO的用途
用于客户进程–服务器进程应用程序中。
FIFO的真正优势在于:服务器可以是一个长期运行的进程(例如守护进程),而且与其客户可以无亲缘关系。作为服务器的守护进程以某个众所周知的路径名创建一个FIFO,并打开该FIFO来读。此后某个时刻启动的客户打开该FIFO来写,并将其请求通过该FIFO发送出去。(客户到服务器)
每个客户在启动时创建自己的FIFO,所用的路径名含有自己的进程ID。每个客户把自己的请求写入服务器的众所周知的FIFO中,该请求含有客户的进程ID以及一个请求文件路径名,服务器根据客户进程ID可以知道客户FIFO的路径名。
来源:CSDN
作者:Mr_慕白
链接:https://blog.csdn.net/weixin_38932035/article/details/104044363