2

我正在开发一个应该通过 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 上似乎很好。

我将实施并测试它,然后我会在这里发布结果。:)

但是,任何更漂亮的解决方案都非常受欢迎!

4

0 回答 0