Ruby thread 超时如何强制退出?

dddd1919 · 发布于 2014年3月15日 · 最后由 dddd1919 回复于 2014年3月17日 · 2663 次阅读
4277

使用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进程,每次都要手动清理。可能是多线程理解不到位,求大神帮忙啊!

共收到 4 条回复
3962
nowherekai · #1 · 2014年3月15日

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 后会正常输出信息退出,第四个、第五个依次类推。

2622
jjym · #2 · 2014年3月15日

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

4277
dddd1919 · #3 · 2014年3月17日

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

4277
dddd1919 · #4 · 2014年3月17日

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

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