Ruby thread 超时如何强制退出?

dddd1919 · 2014年03月15日 · 最后由 dddd1919 回复于 2014年03月17日 · 6060 次阅读

使用 ruby 多线程处理并行任务时,某些线程因为任务执行出现异常(我想可能是挂起了),使得进程最后成了垃圾进程。查 ruby 手册发现Thread#join方法还有个参数,如果加个参数会设置为线程对象的超时时间,过时后自动退出。 写了两个测试: (1)

test_thread = Thread.new {sleep 10; puts "Thread completed" }
test_thread.join(3)
puts  "------------END----------------"

在 thread 的 join 加上参数后三秒线程退出了

(2)根据我的任务场景写了个测试

threads = []
10.times do |i|
  threads << Thread.new do
    sleep i + 1
    puts "This is the #{i} thread!"
 end
end

puts "All threads create completed!"
threads.each {|t| t.join(3) }
puts "------------END----------------"

结果很奇怪:

All threads create completed!
This is the 0 thread!
This is the 1 thread!
This is the 2 thread!
This is the 3 thread!
This is the 4 thread!
This is the 5 thread!
This is the 6 thread!
This is the 7 thread!
This is the 8 thread!
This is the 9 thread!
------------END----------------

按照文档应该输出到 This is the 2 thread! 后其他进程就该退出了,但是十个都执行完了,求解! ps:用多线程执行的单个任务一般不会超过 10s,但是有可能出现无响应的状态,本来想让线程执行超时设置到 30s,这样能保证主进程完毕后退出,但有可能是线程执行异常的问题,过很长时间后发现任务机器上残留几个 ruby 进程,每次都要手动清理。可能是多线程理解不到位,求大神帮忙啊!

Ruby 的 thread 没用过,不过 t.join(3) 会阻塞的,查文档 join "The calling thread will suspend execution and run this thr.Does not return until thr exits or until the given limit seconds have passed."
你的(2)执行时,第一个线程 sleep 1 秒输出信息退出,然后执行第二个线程的 join,输出信息后退出,然后第三个 thread 2 join 执行后 退出,然后第四个 thread 3, 此时 thread 3 已经 sleep 3 秒,执行 join 3 后会正常输出信息退出,第四个、第五个依次类推。

你的主线程在 each 里每一次都等了 3s,所以其余的线程都执行完了。想保证线程退出,你可以在 at_exit 上去 terminate 线程

#1 楼 @nowherekai 懂了,就顾得 thr 并发,没有考虑到 join 是顺序执行的。。。谢谢!

#2 楼 @jjym 线程可能会有异常,目前只能这样了,谢谢!

需要 登录 后方可回复, 如果你还没有账号请 注册新账号