我想测试一个进程是否正常工作,所以我运行:
cmd = "my unix command"
results = `#{cmd}`
如何向命令添加超时,以便如果它花费超过 x 秒,我可以假设它不起作用?
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 # ""
把它放在一个线程中,让另一个线程休眠 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 的更好 :) 这是低科技路线。
线程更简单的方法:
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
对先前答案的一个警告,如果子进程正在使用sudo
,那么你不能杀死孩子,你将创建僵尸进程。
您将需要定期运行Process::waitpid(-1, Process::WNOHANG)
以收集孩子的退出状态并清理进程表(从而清理僵尸)。