4

我想测试一个进程是否正常工作,所以我运行:

cmd = "my unix command"
results = `#{cmd}`

如何向命令添加超时,以便如果它花费超过 x 秒,我可以假设它不起作用?

4

4 回答 4

7

Ruby 附带Timeout 模块

require 'timeout'
res = ""
status = Timeout::timeout(5) {res = `#{cmd}`} rescue Timeout::Error

# a bit of experimenting:

res = nil
status = Timeout::timeout(1) {res = `sleep 2`} rescue Timeout::Error 
p res    # nil
p status # Timeout::Error

res = nil
status = Timeout::timeout(3) {res = `sleep 2`} rescue Timeout::Error 
p res    # ""
p status # ""
于 2012-06-05T19:00:15.357 回答
1

把它放在一个线程中,让另一个线程休眠 x 秒,如果它还没有完成,则杀死第一个线程。

process_thread = Thread.new do
  `sleep 6` # the command you want to run
end

timeout_thread = Thread.new do
  sleep 4   # the timeout
  if process_thread.alive?
    process_thread.kill
    $stderr.puts "Timeout"
  end
end

process_thread.join
timeout_thread.kill

不过 steenslag 的更好 :) 这是低科技路线。

于 2012-06-05T18:54:45.993 回答
0

线程更简单的方法:

p = Thread.new{ 
   #exec here
}
if p.join( period_in_seconds ).nil? then
   #here thread p is still working
   p.kill
else
   #here thread p completed before 'period_in_seconds' 
end
于 2016-10-14T13:25:04.700 回答
0

对先前答案的一个警告,如果子进程正在使用sudo,那么你不能杀死孩子,你将创建僵尸进程。

您将需要定期运行Process::waitpid(-1, Process::WNOHANG)以收集孩子的退出状态并清理进程表(从而清理僵尸)。

于 2017-09-29T14:16:41.890 回答