我正在寻找一个便携式接口到POSIX alarm(2)
(或类似)在Ruby中。也就是说,我希望能够在 n秒之后设置后台计时器来发送信号到当前进程。异步报警信号
我从2006年的ruby-talk列表中发现了一些good discussion,它提供了一个使用dl/import
的解决方案,但这有些破解(尽管是一个整洁的破解),并不是很便携。
我已经看过很多诽谤的Timeout
模块,并且它不会在JRuby下削减它,尽管它与传统解释器一起工作良好。我的程序是使用所述的Readline库小命令行外壳:
TIMEOUT = 5 # seconds
loop do
input = nil
begin
Timeout.timeout(TIMEOUT) do
input = Readline::readline('> ', nil)
end
rescue Timeout::Error
puts "Timeout"
next
end
# do something with input
end
下的JRuby似乎处理块在readline
呼叫和Timeout::Error
(a)该定时器期满后仅抛出(b)该用户输入一个新行。而例外情况没有得到解救。嗯。
于是我想出了以下解决方法:
require 'readline'
class TimeoutException < Exception ; end
TIMEOUT = 5 # seconds
loop do
input = nil
start_time = Time.now
thread = Thread.new { input = Readline::readline('> ', nil) }
begin
while thread.alive? do
sleep(1) # prevent CPU from melting
raise TimeoutException if(Time.now - start_time > TIMEOUT)
end
rescue TimeoutException
thread.exit
puts "Timeout"
end
# do something with input
end
这是...笨重(让我们礼貌)。我只想要alarm(2)
!我真的不想拖入非核心库(例如终结者)。有没有更好的办法?
编辑: 我无法获得另一种选择 - 创建一个睡眠的线程,然后发送一个信号给进程 - 在JRuby下工作。 JRuby吃信号吗?例如:
SIG = 'USR2'
Signal.trap(SIG) { raise }
Process.kill(SIG, Process.pid)
JRuby只是返回,Ruby返回预期的“未处理的异常”错误。
+1为整洁的想法,但我想保持readline(命令行编辑,历史,完成,..)。我已经重写了我的一个类,所以我可以放弃JRuby。使用BouncyCastle进行快速原型设计是非常棒的,但JRuby对于认真的工作仍然很年轻(并且不会和我讨论关于Kernel#select docs !!)。干杯! – 2009-02-03 06:20:06