什么条件导致打开的非阻塞命名管道(fifo)对于读取"不可用"?

UsA*_*R33 13 python linux named-pipes fifo mkfifo

情况:

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

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

什么时候出现这个错误?这似乎非常罕见,因为常见情况返回数据:

  • 如果没有编写器打开管道,则返回空的str('').
  • 如果编写器已打开管道,但fifo中没有数据,则还会返回空的str('')
  • 当然,如果作者将数据放入fifo中,那么将读取该数据.

Nik*_* B. 12

POSIX规范的read系统调用(强调我的):

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

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

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

基本上你的第二个假设是错误的:

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

这将违反规范,我不能在我的机器上重现这种行为(它EAGAIN为我加油).这不是一个大问题,你可以捕获异常并重试:

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
Run Code Online (Sandbox Code Playgroud)