什么条件导致打开的,无阻塞的命名管道(fifo)变为“不可用"?阅读? [英] What conditions result in an opened, nonblocking named pipe (fifo) being "unavailable" for reads?

查看:178
本文介绍了什么条件导致打开的,无阻塞的命名管道(fifo)变为“不可用"?阅读?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况:

new_pipe = os.open(pipe_path, os.O_RDONLY | os.O_NONBLOCK) # pipe_path points to a FIFO
data = os.read(new_pipe, 1024)

该读取偶尔会引发errno -11:资源暂时不可用.

The read occasionally raises errno -11: Resource temporarily unavailable.

何时引发此错误?似乎非常罕见,因为常见情况会返回数据:

When is this error raised? It seems very rare, as the common cases return data:

  • 如果没有写入器打开了管道,则返回空的str('').
  • 如果编写器打开了管道,但FIFO中没有数据,则为空 ('')也将返回
  • 当然,如果作者将数据放入fifo中,则将读取该数据.
  • If no writer has the pipe opened, empty str ('') is returned.
  • If the writer has the pipe opened, but no data is in the fifo, empty str ('') is also returned
  • And of course if the writer puts data in the fifo, that data will be read.

推荐答案

来自 read系统调用(重点是我的)的POSIX规范:

From the POSIX specification of the read system call (emphasis mine):

尝试从空管道或FIFO中读取时:

When attempting to read from an empty pipe or FIFO:

  • 如果没有进程打开要写入的管道,则read()将返回0到 表示文件结束.

  • If no process has the pipe open for writing, read() shall return 0 to indicate end-of-file.

如果某个进程打开了用于写入的管道,并且设置了O_NONBLOCK, read()将返回-1并将errno设置为[EAGAIN].

If some process has the pipe open for writing and O_NONBLOCK is set, read() shall return -1 and set errno to [EAGAIN].

所以基本上您的第二个假设是错误的:

So basically your second assumption is wrong:

如果编写器打开了管道,但fifo中没有数据,则还返回空的str('')

If the writer has the pipe opened, but no data is in the fifo, empty str ('') is also returned

这将违反规范,并且我无法在我的机器上重现该行为(它对我产生了EAGAIN).但是,这不是什么大问题,您可以捕获异常并重试:

This would be against the specification and I can't reproduce that behaviour on my machine (it raises EAGAIN for me). This is not a big problem however, you can just catch the exception and retry:

import errno

def safe_read(fd, size=1024):
   ''' reads data from a pipe and returns `None` on EAGAIN '''
   try:
      return os.read(fd, size)
   except OSError, exc:
      if exc.errno == errno.EAGAIN:
         return None
      raise

这篇关于什么条件导致打开的,无阻塞的命名管道(fifo)变为“不可用"?阅读?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆