Ruby thread 超时如何强制退出?

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

使用 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 线程可能会有异常,目前只能这样了,谢谢!

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