[apue] FIFO:不是文件的文件

众所周知,FIFO中文译为命名管道,是PIPE的升级版。而PIPE是管道,系统提供的一种进程间通信方式,FIFO与PIPE有如下方面不一样:html

1) FIFO须要先在文件系统建立(mkfifo),以后使用文件接口操做(open/close/read/write);而PIPE不与文件系统相关联,建立PIPE后直接读写(pipe),无需打开;git

2) PIPE只能在父子关系的进程间使用,本质是经过fork复制了母进程空间从而扩展到另外一个进程;而FIFO关联的各个进程间更为自由,没必要由fork产生也可使用。github

 

但他们都是管道,本质上就是内核开辟的一块缓存区,虽然FIFO在文件系统有一个入口,可是它和文件有很大不一样,具体体如今使用FIFO的文件接口的几个限制上:缓存

1) 若是读进程以只读方式打开FIFO,若此时尚未写进程打开FIFO,则读进程会阻塞在open上,直到有进程以写方式打开FIFO文件;异步

2) 若是写进程以只写方式打开FIFO,若此时尚未读进程打开FIFO,则写进程会阻塞在open上,直到有进程以读方式打开FIFO文件;测试

3) 若是进程以读写方式打开FIFO,此时open将再也不阻塞,可是若是此时没有写进程向管道内写数据,则读取将阻塞在read上,直到有进程写入数据为止。(须要注意的是若是以前有进程写入过数据,可是该进程在本进程open以前已经关闭FIFO,则相应的数据是读不到的);spa

4) 若是进程以读写方式打开FIFO,此时open将再也不阻塞,无论有没有读进程从管道读数据,写数据(write)都将成功返回,直到底层缓冲区被写满;线程

5) 若是进程以只读且异步方式(O_NONBLOCK)打开FIFO,则不论有没有写进程打开FIFO,都不会阻塞在open上。但若是此时没有写进程写入数据,后续read将返回0;code

6) 若是进程以只写且异步方式(O_NONBLOCK)打开FIFO,若此时尚未读进程打开FIFO,则open返回-1,errno设置为ENXIO(6 /* No such device or address */)htm

 

通常不多用读写方式打开FIFO,由于那样很容易读到本身写入的数据,除非此FIFO就是用来在进程内部多个线程之间使用的。

能够看到上面林林总总的各类限制,指向的一个目标就是:保证读写进程同时打开FIFO并进行数据交换。换句话说,就是FIFO没有任何临时存储数据的能力,错过了,就没了。

从这个意义上说,FIFO根本不是文件。

 

除此以外,FIFO在读写进程退出时的表现,也与PIPE类似,而与文件不一样:

1) 当全部读进程退出后,写进程再写入数据会收到SIGPIPE信号;

2) 当全部写进程退出后,读进程再读取数据read会返回0;

 

对于第1点,特别声明一下,就是在PIPE中,多对一的状况与一对一读写进程不一样,当读进程退出时,多个写进程并无收到SIGPIPE信号,详见下面这篇文章:

多进程管道读写的一些疑问

 

总之,从各方来讲,FIFO都是一个PIPE,而不是一个传统意义上的文件

测试读代码

测试写代码

相关文章
相关标签/搜索