Rubyで並列処理をする方法

Rubyで並列処理をする方法

Rubyで並列処理を行う方法にはいくつかのアプローチがあります。
以下に主要な方法を説明します。

1. スレッドを使用する

Rubyにはスレッドを使用して並列処理を行う機能があります。
スレッドは、同時に複数の処理を実行するための基本的な仕組みです。
スレッドを使うことで、Rubyのプログラムは複数の操作を同時に実行することが可能です。

以下はスレッドを使った並列処理の基本的な例です。

threads = []

3.times do |i|
  threads << Thread.new do
    puts "Thread #{i + 1} is running"
    sleep 2
    puts "Thread #{i + 1} finished"
  end
end

threads.each(&:join)
puts "All threads finished"

このコードでは、3つのスレッドを作成し、それぞれに異なるメッセージを表示させ、2秒間スリープさせます。
threads.each(&:join)を使って、全てのスレッドが終了するまでメインスレッドが待機します。

2. concurrent-ruby ジェムを使用する

concurrent-ruby ジェムは、より高度な並列処理機能を提供します。
これは、スレッドプール、未来、タスクなどの高級な並列処理機能を提供するライブラリです。

以下はconcurrent-rubyを使用したスレッドプールの例です。

require 'concurrent-ruby'

pool = Concurrent::FixedThreadPool.new(3)

3.times do |i|
  pool.post do
    puts "Task #{i + 1} is running"
    sleep 2
    puts "Task #{i + 1} finished"
  end
end

pool.shutdown
pool.wait_for_termination
puts "All tasks finished"

この例では、スレッドプールを作成し、3つのタスクをポストして処理を実行します。
スレッドプールが全てのタスクを処理し終えるまで待機します。

3. Parallel ジェムを使用する

parallel ジェムは、複数のプロセスを使って並列処理を行うための便利なツールです。
これにより、Rubyプログラムで複数のCPUコアを有効に活用することができます。

以下はparallelジェムを使った並列処理の例です。

require 'parallel'

results = Parallel.map(1..3, in_processes: 3) do |i|
  puts "Process #{i} is running"
  sleep 2
  "Result from process #{i}"
end

results.each { |result| puts result }
puts "All processes finished"

このコードでは、Parallel.mapメソッドを使用して、3つのプロセスを生成し、それぞれのプロセスで作業を実行します。
結果はresultsに収集され、すべてのプロセスが終了するまで待機します。

4. fibers を使用する

Rubyのfibersは、軽量な並行処理を実現するための機構です。
スレッドよりも軽量で、より効率的な並行処理が可能ですが、並列処理ではなく協調的な並行処理です。

以下はfibersを使用した例です。

fiber1 = Fiber.new do
  puts "Fiber 1 started"
  Fiber.yield
  puts "Fiber 1 resumed"
end

fiber2 = Fiber.new do
  puts "Fiber 2 started"
  Fiber.yield
  puts "Fiber 2 resumed"
end

fiber1.resume
fiber2.resume
fiber1.resume
fiber2.resume

puts "All fibers finished"

このコードでは、2つのファイバーを作成し、それぞれのファイバーを中断・再開することで、協調的な並行処理を実現しています。

これらの方法は、並列処理のニーズやシステムの特性によって使い分けることができます。
スレッドは軽量ですが、CPUバウンドな処理には限界があります。
concurrent-rubyやparallelは、より高度な並列処理をサポートし、複数のコアを活用するのに適しています。
fibersは、軽量な並行処理が必要な場合に便利です。