IO::EAGAINWaitReadable: 资源暂时不可用 - 读取将会阻塞

7
当我尝试使用“socket”库中的“read_nonblock”方法时,出现以下错误。
IO::EAGAINWaitReadable: Resource temporarily unavailable - read would block

但是当我在终端上通过IRB尝试时,它可以正常工作。

我该如何让它读取缓冲区?

1个回答

3
当我尝试使用“socket”库中的“read_nonblock”方法时,出现以下错误。如果缓冲区中没有准备好的数据,则这是预期行为。自Ruby版本2.1.0起,异常“IO::EAGAINWaitReadable”源自旧版本,您必须使用额外的端口选择和重试来捕获“IO::WaitReadable”。因此,请按照ruby文档中的建议操作。
begin
   result = io.read_nonblock(maxlen)
rescue IO::WaitReadable
   IO.select([io])
   retry
end

对于更新版的 Ruby,您需要捕获 IO::EAGAINWaitReadable,但只需进行超时或无限重试读取。我没有在文档中找到示例,但记得它是没有端口选择的:

begin
   result = io.read_nonblock(maxlen)
rescue IO::EAGAINWaitReadable
   retry
end

然而,我的一些调查表明,在IO::EAGAINWaitReadable上进行端口选择也更好,这样你就可以获得:

begin
   result = io.read_nonblock(maxlen)
rescue IO::WaitReadable, IO::EAGAINWaitReadable
   IO.select([io])
   retry
end

为了支持两个版本的异常代码,请在lib/核心下的if子句中声明IO :: EAGAINWaitReadable的定义:
if ! ::IO.const_defined?(:EAGAINWaitReadable)
   class ::IO::EAGAINWaitReadable; end
end

拯救IO::WaitReadable应该足以包含IO::EAGAINWaitReadable吗?irb(main):005:0> IO::EAGAINWaitReadable < IO::WaitReadable => true - gerky
@gerky 看起来这是真的,不过并非所有版本都是如此(在某些版本中我看到 EWaitReadable 被忽略了)。 - Малъ Скрылевъ
嗯...我发布的那行代码是来自Ruby 2.3.0 irb。我还看到了这个:http://ruby-doc.org/core-2.3.0/IO.html#method-i-read_nonblock,似乎只需要捕获IO::WaitReadable就足够了? - gerky
@gerky 可能是针对特定版本,或者是 Rubinius 或 JRuby。 - Малъ Скрылевъ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接