收集 Ruby 并行 Gem 的结果

Collecting results for Ruby Parallel Gem

Ruby的Parallel gem貌似很强大,但是我用它建个合集有点问题

以进程设置为 0 为例:

[174] pry(main)> @array = []
=> []
[175] pry(main)> Parallel.each(1..10, :in_processes=>0) {|x| @array.push(Random.rand(10))}
=> 1..10
[176] pry(main)> @array
=> [7, 3, 5, 6, 1, 5, 4, 4, 5, 1]

但是当我们将进程设置为 2 时:

[177] pry(main)> @array = []
=> []
[178] pry(main)> Parallel.each(1..10, :in_processes=>2) {|x| @array.push(Random.rand(10))}
=> 1..10
[179] pry(main)> @array
=> []

显然,这甚至不是构建随机值数组的最佳方法,我想要了解的是,在循环结束后附加到 @array 的值不存在多个进程。这是范围问题还是我误解了分叉的工作原理?

Parallel 的默认模式通过分叉您的进程并在 sub-processes 中工作(在我看来,这是一个 gigantic hack)。 Child 进程不会对 parent 的内存进行写访问;在 child 中所做的更改不会保留到 parent。

您将只能通过 gem 的设施与您的 parent 进程通信,这些设施从 child 捕获 return 值。 Parallel.map 提供了一种机制,通过该机制传入的数据在 parent 端进行编组,然后在 child 进行解组,继续处理,然后将结果编组并传递回parent,并收集到一个结果数组中。当分叉 child 死亡时,任何过去的东西都将是 "thrown away"。

考虑改用线程(并正确同步对共享变量的访问)。如果您需要 multi-core 并发性(即,您正在执行不阻塞 IO 的并行工作),您应该考虑 JRuby,它没有 GIL 并且可以本机执行多个 Ruby 个并行线程。