【发布时间】:2012-06-09 19:35:24
【问题描述】:
我想测试一个进程是否正在运行,所以我运行:
cmd = "my unix command"
results = `#{cmd}`
如何为命令添加超时,以便在超过 x 秒的情况下我可以假设它不起作用?
【问题讨论】:
我想测试一个进程是否正在运行,所以我运行:
cmd = "my unix command"
results = `#{cmd}`
如何为命令添加超时,以便在超过 x 秒的情况下我可以假设它不起作用?
【问题讨论】:
Ruby 附带 Timeout module。
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 # ""
【讨论】:
Timeout::Error。
把它放在一个线程中,让另一个线程休眠 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) 来收集子进程的退出状态并清理进程表(从而清理僵尸进程)。
【讨论】: