我正在寻找alarm(2)
Ruby中POSIX (或类似)的可移植接口。也就是说,我希望能够设置后台计时器,在n秒后向当前进程发送信号。
我在2006年的ruby-talk列表中找到了一些很好的讨论,它提供了一个使用的解决方案dl/import
,但这有点像黑客(尽管是一个整洁的黑客)并且不是很便携。
我看过备受诟病的Timeout
模块,虽然它与传统的解释器一起使用,但它不会在JRuby下删除它。我的程序是一个使用Readline库的小命令行shell:
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返回预期的“未处理异常”错误。
发布于 2019-06-04 10:34:06
对不起,我没有回答你在X秒后向进程发送信号这个更大的问题,但似乎所有你想做的就是在等待输入X秒后超时,如果这是然后我会说你正在寻找Kernel.select:D
我个人从来没有使用过这个,但在谷歌做了“非阻塞获取”,并随后探索链接后,我发现这两个是非常宝贵的讨论:
http://www.ruby-forum.com/topic/126795(讨论多线程获取)
http://www.ruby-forum.com/topic/121404(第二篇文章中Kernel.select的说明)
这是一个如何使用它的示例。这将打印出您的提示并等待输入...如果五秒后没有输入,则程序将结束。如果有输入,只要有输入就会将其吐出并结束...显然,您可以根据自己的需要对其进行修改。
def prompt
STDOUT.write "> "
STDOUT.flush
end
def amusing_messages
[ "You must enter something!",
"Why did you even start me if you just wanted to stare at me?",
"Isn't there anything better you could be doing?",
"Just terminate me already... this is getting old",
"I'm waiting..."]
end
prompt
loop do
read_array, write_array, error_array = Kernel.select [STDIN], nil, nil, 5
if read_array.nil?
puts amusing_messages[rand(amusing_messages.length)]
else
puts "Result is: #{read_array[0].read_nonblock(30)}"
end
prompt
end
它可能没有您想要的那么优雅,但它绝对可以完成工作而不会乱用线程。不幸的是,如果你想要更强大的东西(定时器/向过程发送信号),这对你没有帮助,遗憾的是,我不知道这是否适用于JRuby。很想知道它是否确实:)
https://stackoverflow.com/questions/-100009071
复制相似问题