28
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Parallelのマルチプロセスでハマったこと

Last updated at Posted at 2017-07-11

Parallelのマルチプロセスでハマったこと

マルチプロセスにおいて子プロセスは親プロセスの変数に影響を及ぼさない

まず、以下のようなマルチスレッドで実行されるコードをみましょう。

Rubyコード
multi_threads.rb
require 'parallel'
files = [1, 2, 3, 4, 5, 6, 7 ,8, 9 ,10 ,11, 12, 13]
@array = []
Parallel.each(files, :in_threads=>10) {|x|
  @array.push(x)
}

puts @array
結果
[1, 2, 4, 3, 5, 7, 6, 8, 9, 11, 13, 12, 10]

上記のものをマルチプロセスで実行するようにしようとして、 :in_threads のところを単純に :in_processes に変更しました。そうすると。。

Rubyコード
multi_processes.rb
require 'parallel'
files = [1, 2, 3, 4, 5, 6, 7 ,8, 9 ,10 ,11, 12, 13]
@array = []
Parallel.each(files, :in_processes=>10) {|x|
  @array.push(x)
}

puts @array
結果
[]

何にも出力されませんでした!!!なんだって!!!

理由

Parallelでは子プロセスをforkして子プロセス内でロジックを遂行していきますが、同じ変数であっても親プロセスと各子プロセスの変数はメモリ上別領域にあるためです。
スクリーンショット 2017-07-11 21.13.42.png

以下のコードを実行して結果を見ればわかるように、子プロセスで累積した結果は、親プロセスに何の影響も及ぼしません。

コード
multi_processes_test.rb
require 'parallel'
files = [1, 2, 3, 4, 5, 6, 7 ,8, 9 ,10 ,11, 12, 13]
@array = []
puts "parent pid: #{$$}"
Parallel.each(files, :in_processes=>10) {|x|
  puts "pid:#{$$} #{x} #{@array}"
  @array.push(x)
}
puts "parent pid:#{$$} #{@array}"
結果
parent pid: 65100
pid:65101 1 []
pid:65102 2 []
pid:65104 3 []
pid:65106 4 []
pid:65101 5 [1]
pid:65110 7 []
pid:65103 8 []
pid:65104 9 [3]
pid:65102 12 [2]
pid:65106 13 [4]
pid:65105 10 []
pid:65107 11 []
pid:65109 6 []
parent pid:65100 []

対処方法

Parallel.map を使用することです。

Rubyコード
improved_multi_processes.rb
require 'parallel'
files = [1, 2, 3, 4, 5, 6, 7 ,8, 9 ,10 ,11, 12, 13]
@array = []
@array = Parallel.map(files, :in_processes=>10) {|x|
  x
}

puts @array
結果
[1, 2, 4, 3, 5, 7, 6, 8, 9, 11, 13, 12, 10]

来た!!

このロジックいける理由は、子プロセスが死ぬときに、その戻り値を親プロセスに伝え、親プロセスがそれを収集して結果を返すためだそうです。。(僕もロジックはみてないので自身はありませんwww)

以上です。

28
23
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?