使用 Ruby 的“准备好了吗?”带有gets、puts等的IO方法
Posted
技术标签:
【中文标题】使用 Ruby 的“准备好了吗?”带有gets、puts等的IO方法【英文标题】:Using Ruby's "ready?" IO method with gets, puts, etc 【发布时间】:2010-12-19 06:11:18 【问题描述】:标准 Ruby 库“io/wait”在 IO 对象ready?
上提供了一个方法,如果有可用输入则返回非零,否则返回 nil 或 false。我知道sysread
和syswrite
等一些方法不能安全地与gets
和read
等更高级别的方法一起使用,并且想知道ready?
是否可以安全地与更高级别的方法混合使用。 ready 方法似乎比依赖IO.select
更有用,而且可能更优雅,但是,令人惊讶的是,我还没有看到它用得太多。 documentation 中没有任何内容表明与 read
或 gets
一起使用是不安全的,我只是想确保我没有混合不兼容的方法,这些方法最终可能在读/写套接字时导致意外行为.
编辑:我想我应该提到我使用的是 Ruby 1.8.7。
【问题讨论】:
【参考方案1】:我对 Ruby 没有太多经验,但我对 libc 有很多经验,我认为是的,它是安全的。用 select() 或 poll() 实现“就绪”的可能性非常好......
如果“就绪”的行为类似于一个 select(),它已通过 tv_sec 和 tv_usec 为零的时间值,那么“就绪”的缺点是您将旋转...您可以将超时传递给就绪?
【讨论】:
ready?
方法似乎完全是非阻塞的,我假设在这一切之下,ruby 正在以某种容量缓冲它的套接字,或者它的行为类似于 select
很短超时。
我在几个地方找到了 io/wait Ruby 库的实际 C 源代码(例如:cvs.opensolaris.org/source/xref/webstack/webstack/trunk/src/…)我从大学开始就没有使用 C 进行低级套接字编程,但是似乎除了一些初步检查之外,真正的工作还是回到了ioctl(file_num, FIONREAD &n)
基于使用 FIONREAD 深入研究 ioctl 的行为,我相信您是正确的,只要 IO(在我的情况下为 TCPSocket)对象支持调用,就可以安全地与“更高水平”读取方法。感谢您的洞察力。以上是关于使用 Ruby 的“准备好了吗?”带有gets、puts等的IO方法的主要内容,如果未能解决你的问题,请参考以下文章