ParallelというGemで並列処理を試してみました。
インストール
インストールはBundlerを使いました。
source "https://rubygems.org" gem "parallel"
使い方
使い方は下の通りです。
1,2,3を引数にしたブロックを並列に実行してくれます。
require 'parallel' puts 'Start' Parallel.each([1, 2, 3]) do |i| puts i end puts 'End'
結果は下の通りです。
並列なことを確かめるために、下のようにiが2の時に1秒待つようにしてみました。
require 'parallel' puts 'Start' Parallel.each([1, 2, 3]) do |i| sleep 1 if i == 2 puts i end puts 'End'
結果は下の通りです。
1,3,2の順番に出力されました。
下のようにスレッド数を指定する事もできます。
require 'parallel' Parallel.each([1, 2, 3], in_threads: 2) do |i| puts i end
スレッド数を1にすると、並列ではなくなるので全てが順番に実行されます。
require 'parallel' Parallel.each([1, 2, 3], in_threads: 1) do |i| sleep 1 if i == 2 puts i end
スレッドではなくプロセスを使う事もできます。
require 'parallel' Parallel.each([1, 2, 3], in_processes: 2) do |i| puts i end
プロセスはブロック内での変数の変更が共有されません。
require 'parallel' array = [] Parallel.each([1, 2, 3], in_processes: 2) do |i| array.push(i) end p array # → [] array = [] Parallel.each([1, 2, 3], in_thread: 2) do |i| array.push(i) end p array # → []
変数の共有をしたい場合は下のようにmapを使います。
require 'parallel' array = Parallel.map([1, 2, 3]) do |i| i end p array # → [1, 2, 3]
mapの返り値は引数の順番を保持してくれます。
下のようにi==2の時だけsleepしても結果は1, 2, 3になりました。
require 'parallel' array = Parallel.map([1, 2, 3], in_thread: 2) do |i| sleep 1 if i == 2 i end p array # → [1, 2, 3]
もし別々の処理を実施したい場合は下のような書き方もできます。
require 'parallel' Parallel.each([ -> { p 1 }, -> { p 2 }, -> { p 3 }, ]) do |l| l.call end