【问题标题】:How to read named FIFO non-blockingly?如何非阻塞地读取命名的 FIFO?
【发布时间】:2013-01-15 19:59:06
【问题描述】:

我创建了一个 FIFO,并定期从 a.py 以只读和非阻塞模式打开它:

os.mkfifo(cs_cmd_fifo_file, 0777)
io = os.open(fifo, os.O_RDONLY | os.O_NONBLOCK)
buffer = os.read(io, BUFFER_SIZE)

从b.py,打开fifo进行写入:

out = open(fifo, 'w')
out.write('sth')

那么a.py会报错:

buffer = os.read(io, BUFFER_SIZE)

OSError: [Errno 11] Resource temporarily unavailable

有人知道怎么回事吗?

【问题讨论】:

标签: python nonblocking fifo


【解决方案1】:

根据read(2)的手册页:

   EAGAIN or EWOULDBLOCK
          The  file  descriptor  fd refers to a socket and has been marked
          nonblocking   (O_NONBLOCK),   and   the   read   would    block.
          POSIX.1-2001  allows  either error to be returned for this case,
          and does not require these constants to have the same value,  so
          a portable application should check for both possibilities.

所以你得到的是没有可供阅读的数据。像这样处理错误是安全的:

try:
    buffer = os.read(io, BUFFER_SIZE)
except OSError as err:
    if err.errno == errno.EAGAIN or err.errno == errno.EWOULDBLOCK:
        buffer = None
    else:
        raise  # something else has happened -- better reraise

if buffer is None: 
    # nothing was received -- do something else
else:
    # buffer contains some received data -- do something with it

确保您已导入 errno 模块:import errno

【讨论】:

  • 试用后,a.py raise: UnboundLocalError: local variable 'buffer' referenced before assignment
  • @chaonin 我试图猜测原因是什么(我之前没有使用缓冲区),并更新了我的示例。希望现在更清楚了。
  • io = os.open(fifo, os.O_RDONLY | os.O_NONBLOCK) try: buffer = os.read(io, BUFFER_SIZE) 除了 OSError as err: if err.errno == errno.EAGAIN或 err.errno == errno.EWOULDBLOCK: 传递 else: raise err jobs_infile = shlex.split(buffer) os.close(io)
  • 出于兴趣:EAGAIN 和 EWOULDBLOCK 都有效地表示同一件事。事实上,在某些系统上它们是相同的值。不过,同时检查两者是个好主意。
  • @lxs 事实上,如果你想便携,你必须这样做,正如 read(2) 手册页所建议的那样。这很不方便,在 python3.3 中,我们会改为捕获 BlockingIOError(这也告诉我们写入了多少个字符)。
【解决方案2】:
out = open(fifo, 'w')

谁会为你关闭它? 用这个替换你的 open+write:

with open(fifo, 'w') as fp:
    fp.write('sth')

统一更新: 好的,不仅仅是做这个:

out = os.open(fifo, os.O_NONBLOCK | os.O_WRONLY)
os.write(out, 'tetet')

【讨论】:

  • 这并没有回答问题,考虑到给出的代码显然是 sn-ply,这也不相关。 (-1)
  • 如果您的修改是为了解决我的投诉,但它没有。
猜你喜欢
  • 1970-01-01
  • 2017-04-26
  • 1970-01-01
  • 2011-09-23
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多