「dRubyで並列処理 - ohacの日記」を読んだ
dRubyで並列処理 - ohacの日記をいう記事を見たのですが
自分の読解力不足だったので時間をかけて読んだ。
面白かったのでコメントをつけて紹介させて頂きます。
なにか
このサンプルコードは500万回の疑似乱数の中から最も0に近い実数を見つけだすというプログラムです。
http://d.hatena.ne.jp/ohac/20091211/1260503455
ソースコード
#!/usr/bin/ruby require 'drb/drb' class MonteCarlo def initialize(seed) srand(seed) end #引数:何個の数を調べるか #返値:一番小さかった数 def dice(n) best = rand n.times do r = rand best = r if r < best end best end end #プロセッサの数(並列にする数) PROCESSORS = (ARGV[0] || 1).to_i pids = [] #プロセッサの数だけdRubyサーバとdRubyクライアントを生成する #workersはMonteCarloの分散オブジェクトの配列 workers = PROCESSORS.times.map do |i| uri = "druby://localhost:#{12345 + i}" pids << fork { DRb.start_service(uri, MonteCarlo.new(i)); sleep } DRbObject.new_with_uri(uri) end begin n = 5000000 / PROCESSORS q = Queue.new sleep 0.1 ts = workers.map do |foo| #dice(n)をThreadを使って(ほぼ)同時に呼び出し #処理はforkされたdRubyサーバが行うのでRubyでもネイティブスレッドのように動作する Thread.start(foo) {|f| q.push(f.dice(n))} end ts.each{|t| t.join} #子Thread内で例外が起きていればjoinで捕捉できる p q.size.times.map{q.pop}.min #キューを配列にしてminで最小値を取得 ensure pids.each {|pid| Process.kill(:TERM, pid)} #例外が発生していればdRubyサーバを落とす end
見所はやはり、連続でdRubyサーバをforkしつつ分散オブジェクトをつくり、分散オブジェクトをThreadで非同期で呼び出すというところです。
dRubyの珍しい使い方なんじゃないでしょうか。とても面白いです。