我正在尝试运行多个任务,每个任务都访问数据库,并且我正在尝试将这些任务运行到单独的执行线路中。
我玩了玩,试过设置为 true 的 allow_concurrency 或 config.thread_safe!但是我遇到了不确定的错误,例如有时缺少一个类,或者一个常量......
这是一些代码
grabbers = get_grabber_name_list
threads = []
grabbers.each { |grabber|
threads << Thread.new {
ARGV[0] = grabber
if (@@last_run_timestamp[grabber.to_sym].blank? || (@@last_run_timestamp[grabber.to_sym] >= AbstractGrabber.aff_net_accounts(grabber, "grab_interval").seconds.ago))
Rake::Task["aff_net:import:" + grabber].execute
@@last_run_timestamp.merge!({grabber.to_sym => Time.now})
end
}
}
threads.each {|t| t.join }
谢谢
最佳答案
我最近实现了一个使用线程的 Rails 应用程序并有一些发现:
首先,如果您要在线程外写入任何数组或散列(即复杂类型),请将它们包装在互斥体中。在我看来,散列和数组引用可能不是线程安全的。哈希/数组元素索引似乎不太可能不是线程安全的,但我所知道的是,在写入之前将外部数据结构放入互斥量后,问题就消失了。
其次,当线程终止时关闭您的 ActiveRecord 连接,否则您最终可能会创建大量过时的连接。这是一个 post about how to do this .我不知道它是否仍然适用于 Rails 版本 > 2.2,但在我开始明确关闭连接后,我的问题就消失了。作者建议猴子修补 ActiveRecord 自动执行此操作,但我决定在我的代码中显式释放连接。
这是一个适用于我的代码示例:
mutex = Mutex.new
my_array = []
threads = []
1.upto(10) do |i|
threads << Thread.new {
begin
do_some_stuff
mutex.synchronize {
# You'd think that each thread would only touch its own personal
# array element but without a mutex, I run into problems.
my_array[i] = some_computed_value
}
ensure
ActiveRecord::Base.connection_pool.release_connection
end
}
}
threads.each {|t| t.join}
顺便说一下,如果您使用线程来利用多核 CPU,则需要使用 JRuby。据我所知,JRuby 是唯一可以利用 native CPU 线程的实现。如果您使用线程以便在等待网络连接或其他一些非 CPU 任务时可以做其他事情,那么这不是问题。
关于ruby-on-rails - Rails 线程 - 多任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1673097/