Ruby on rails 并发Rails迭代/操作
通常我们逐个迭代数组:Ruby on rails 并发Rails迭代/操作,ruby-on-rails,ruby,Ruby On Rails,Ruby,通常我们逐个迭代数组: a = [1, 2, 3, 4] b = [] a.each do |x| b << x * 5 end b = [5, 10, 15, 20] 如何做到这一点?由于GIL,MRI不能实现真正的多核并行;线程实际上并不能提高CPU限制任务的性能(尽管在IO限制任务上确实如此);您需要运行JRuby或Rubinius来获得CPU绑定任务的并行性,因为它们实际上可以并发地跨多个内核分配工作 也就是说,假设您运行的VM提供了真正的并行性: b = a.ma
a = [1, 2, 3, 4]
b = []
a.each do |x|
b << x * 5
end
b = [5, 10, 15, 20]
如何做到这一点?由于GIL,MRI不能实现真正的多核并行;线程实际上并不能提高CPU限制任务的性能(尽管在IO限制任务上确实如此);您需要运行JRuby或Rubinius来获得CPU绑定任务的并行性,因为它们实际上可以并发地跨多个内核分配工作 也就是说,假设您运行的VM提供了真正的并行性:
b = a.map {|x|
Thread.new {
Thread.current[:out] = x * 5
}
}.map {|t| t.join; t[:out] }
(这段代码非常难看,应该根据实际使用情况进行重构。它还将按照创建线程的顺序返回结果,同时仍然并行化任务。)
这里的要点是1)在线程局部变量中传播返回值(因此您不必对共享值执行调用;如果您想这样做,则需要引入互斥),以及2)在创建的每个线程上调用
#join
,因此,我们可以确定创建的每个线程都已完成运行。由于GIL,MRI无法实现真正的多核并行;线程实际上并不能提高CPU限制任务的性能(尽管在IO限制任务上确实如此);您需要运行JRuby或Rubinius来获得CPU绑定任务的并行性,因为它们实际上可以并发地跨多个内核分配工作
也就是说,假设您运行的VM提供了真正的并行性:
b = a.map {|x|
Thread.new {
Thread.current[:out] = x * 5
}
}.map {|t| t.join; t[:out] }
(这段代码非常难看,应该根据实际使用情况进行重构。它还将按照创建线程的顺序返回结果,同时仍然并行化任务。)
这里的要点是1)在线程局部变量中传播返回值(因此您不必对共享值执行调用;如果您想这样做,则需要引入互斥),以及2)在创建的每个线程上调用
#join
,因此,我们可以确定创建的每个线程都已完成运行。您没有真正的并行性。除非您使用的是更好的ruby(Rubinius或JRuby),否则有一个非常好的gem,它模拟并发处理,尽管在当前的YARV或MRI实现中无法避免GIL。您没有真正的并行性。除非您使用的是更好的ruby(Rubinius或JRuby),否则有一个非常好的gem,名为,它模拟并发处理,尽管在当前的YARV或MRI实现中无法避免GIL。