在 jruby-1.7.6 上运行的rake任务中,我按需生成了许多线程并存储了每个生成的线程:
puts Thread.current # => #<Thread:0x1e95aeb7>
Thread.current[:spawned_threads] = {}
# New thread spawned for every new request and stored and
# Thread.current obviously remains the same:
puts Thread.current # => #<Thread:0x1e95aeb7>
thread_object = Thread.new {
# code in infinite loop
}
Thread.current[:spawned_threads]["thread_#{counter}"] = thread_object
当我退出rake任务时,我终止所有生成的线程。我使用信号处理程序:
trap('INT') {
terminate_threads
exit!
}
def terminate_threads
puts Thread.current # => #<Thread:0x7604790c> A different thread!
puts Thread.current[:spawned_threads] # => nil
Thread.current[:spawned_threads].each do |key, thread| # Error!!!
thread.terminate
end
end
解决方法:Thread.list.last[:spawned_threads]
拥有我生成的所有线程。
但等等,
RUBY 1.9.3中的相同代码工作精细。 Thread.current仍然相同。
问题:
Thread.current
在信号捕获期间有所不同? PLUS,在信号处理程序中(再次),当我尝试访问已经创建的Redis连接时,它无限期地停止,什么都不返回! [仅在JRuby中发生,不确定是否与信号处理有关。]
答案 0 :(得分:0)
我认为没有任何保证你的信号处理程序会发生什么线程。即使在像C with pthreads这样的其他语言中,这种事情也很复杂。
我也怀疑Ruby 强制要求一个特定的线程会收到你的信号,只是碰巧“主”线程就是那个。这可能在未来发生变化。
您应该重新构建代码,以便有一个众所周知的地方可以从任何线程发送消息。这可能采取全局变量的形式。然后,您需要为该对象的方法提供适当的多线程保护,因为您永远不知道将调用方法的线程以及何时。