我正在开发一个应该通过 USB 连接到串行设备的多平台 Ruby 程序。首先我使用的是serialport gem(1.0.4),但后来我遇到了一些奇怪的问题,不得不放弃它。然后我继续通过 Ruby 的 IO 类进行通信,如下所示:
@port = IO.new IO.sysopen(path, mode), mode
通过 syswrite 和 sysread 进行通信在 Linux 和 Windows 中都是完美的。
通信完成后,我尝试设置超时,以便在发生任何不同步时程序不会挂起。全部在 Linux 端使用 timeout.rb 完成,但在调用任何 IO 读取方法(sysread、getc、gets、getbyte ......我都试过了!)之后,Windows 不会让我再次控制解释器。
我尝试了终结者,但它甚至无法运行,抛出参数异常而不是超时——即使在 Linux 中!:
require 'terminator'
Terminator.terminate 2 do
sleep 4
end
产生:
/var/lib/gems/1.9.1/gems/terminator-0.4.4/lib/terminator.rb:164: Use RbConfig instead of obsolete and deprecated Config.
ArgumentError: wrong number of arguments (1 for 0)
from /var/lib/gems/1.9.1/gems/terminator-0.4.4/lib/terminator.rb:127:in `block in terminate'
from (irb):12:in `call'
from (irb):12:in `sleep'
from (irb):12:in `block in irb_binding'
from /var/lib/gems/1.9.1/gems/terminator-0.4.4/lib/terminator.rb:134:in `call'
from /var/lib/gems/1.9.1/gems/terminator-0.4.4/lib/terminator.rb:134:in `terminate'
from (irb):11
from /usr/bin/irb:12:in `<main>'
由于 SystemTimer 依赖于 UNIX 信号并且在 Windows 上不起作用(它只是包装 timeout.rb),我被一个多平台程序卡住了,它在 Windows 上运行时会永远挂起,尽管在 Linux 上很好。
有什么方法可以在 Windows 上设置串行端口读取超时?也许是一个 win32api 调用?
感谢您的时间。:)
编辑:
我相信我找到了解决这个问题的方法,虽然它真的很臭。
代替
Timeout::timeout 0.5 do
gets
end
我试过了
begin
Timeout::timeout 0.5 do
Thread.new do
gets
end.join
end
rescue
"Expired :)"
end
在 IRB 上似乎很好。
我将实施并测试它,然后我会在这里发布结果。:)
但是,任何更漂亮的解决方案都非常受欢迎!