USB経由でシリアルデバイスに接続するマルチプラットフォームRubyプログラムを開発しています。最初は serialport gem (1.0.4) を使用していましたが、いくつかの奇妙な問題に遭遇し、削除する必要がありました。次に、次のように、Ruby の IO クラスを介して通信を行いました。
@port = IO.new IO.sysopen(path, mode), mode
syswrite と sysread による通信は、Linux と Windows の両方で完璧です。
通信が完了したら、タイムアウトを設定して、非同期が発生してもプログラムがハングしないようにしました。すべて Linux 側で timeout.rb を使用して実行されますが、Windows では、IO 読み取りメソッド (sysread、getc、gets、getbyte など) を呼び出した後、インタープリターを再び制御することはできません。すべて試しました!)。
Terminator を試してみましたが、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では問題ないようです。
実装してテストし、結果をここに投稿します。:)
ただし、より優れたソリューションは大歓迎です。