是否应该在刚刚从该 FIFO 读取所有数据之后从 FIFO 块中读取?

Posted

技术标签:

【中文标题】是否应该在刚刚从该 FIFO 读取所有数据之后从 FIFO 块中读取?【英文标题】:Should a read from FIFO block after all the data was just read from that FIFO? 【发布时间】:2015-03-20 18:41:16 【问题描述】:

我正在学习 Linux 中的管道编程,但无法理解管道/FIFO 管理。

我编写了一个小程序,它打开了我创建的 FIFO(在执行程序之前,我在终端中执行了mkfifo newfifo)。然后我反复读取并转储我的字符缓冲区。我正在使用来自另一个终端的 cmd 行的 echo "message" > newfifo 填充 FIFO。

问题是,当我写入 FIFO 时,我可以读取缓冲区中的数据,但随后读取不再阻塞。我的理解是,在我从 FIFO 中读取数据后,FIFO 应该是空的,并且读取应该阻塞。我是在想这个错误,还是我对 FIFO 的管理不正确?

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>

#define NEWPIPE "./newfifo"

void main()

  int great_success = 0; 
  int fd;
  char buffer[20];

  fd = open(NEWPIPE, O_RDONLY);

  while (1) 
    great_success = read(fd, buffer, 20);

    if (great_success < 0) 
      printf("pipe failed\n");
     else 
      printf("buffer : %s\n", buffer);
      printf("great_success = %d\n", great_success);
      great_success = 0;
    
  

【问题讨论】:

相关全面:***.com/a/17384067/132382 【参考方案1】:

您对 fifos 工作原理的理解不正确。它们很像管道:如果写端关闭(回显命令已终止),则读端将读取文件尾(EOF),即返回 0。

请注意,当您打开 fifo 时,它不会被读取阻塞。阻塞系统调用是 open() 系统调用,如http://linux.die.net/man/4/fifo中所述

【讨论】:

【参考方案2】:

因为进程(echo "message" &gt; newfifo) 是一个短程序,所以很快就终止了。一旦进程终止,管道就没有写端,所以另一个进程中的读端会得到一个 EOF。

【讨论】:

以上是关于是否应该在刚刚从该 FIFO 读取所有数据之后从 FIFO 块中读取?的主要内容,如果未能解决你的问题,请参考以下文章

PCI9054进行DMA操作时,如何设置FIFO?

FIFO - 从顶层进程读取,从底层进程写入

ZeroMQ 和本地 FIFO

从应用程序支持文件夹中删除文件后应用程序读取数据

拦截先进先出

在 FIFO 到达时从 FIFO 中读取数据(linux)