我正在尋找一個便攜式接口到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