我有一个简单的rake任务,每个用户执行一些操作。像这样的东西:
task users_actions: :environment do ||
User.all.each { |u|
# Some actions here
}
end
问题是,在完成一个用户之前,它不会从下一个用户开始。我想要的是并行执行这些操作。我该怎么做?甚至有可能?
谢谢,
如果有一个好的库可用,最好使用它,而不是从头开始实现所有内容。concurrent-ruby
有各种用于编写并发代码的实用程序类,但我不确定它们是否适合这个用例;不管怎样,我会教你如何从头开始。
首次引入thread
库:
require 'thread'
制作一个线程安全队列,并将所有用户粘在上面:
queue = Queue.new
User.all.each { |user| queue << user }
启动一定数量的工作线程,并使它们处理队列中的项目,直到完成所有操作。
threads = 5.times.collect do
Thread.new do
while true
user = queue.pop(true) rescue break
# do something with the user
# this had better be thread-safe, or you will live to regret it!
end
end
end
然后等待,直到所有线程完成:
threads.each(&:join)
同样,请确保处理每个用户的代码是线程安全的!多线程的力量掌握在你的手中,不要滥用它!
注意:如果您的用户处理代码非常占用CPU,您可以考虑在Rubinius或JRuby上运行它,这样多个线程可以同时运行Ruby代码。