マルチスレッド難しい
アルバイト先からAmazon.co.jp: dRubyによる分散・Webプログラミング: 関 将俊: 本を借りてマルチスレッドのプログラムを久しぶりに書いた。
もうデットロックしまくりで困る。rubyは言語レベルのスレッドだからなのかすべてのスレッドが停止するとデットロックとして検出してくれる。高性能だねぇ。
本の中でバリア同期の実装が紹介されていたけど、rindaを使うことが前提なので自分で使わないバージョンを作ってみた。(rindaについてはRuby Reference Manual - るりま)popのブロックを積極的に利用している。
require 'thread' class LocalBarrier def initialize(n) @n = n @waits = Queue.new @block = Queue.new end def sync(current) @waits.push(current) @block.push(true) if @waits.length == @n @block.pop @block.push(true) end end
n個itemがたまったら同期が完了したことになる。Queueにはtopメソッドが存在しないので、popしたあとpushし直している。
rinda版見たく実装するためにはmutexをつかってちゃんと実装しないとだめっぽいなぁ。[key, 0]で待ってるrinda版は確かにかっこいいよ。
第二案。トリッキーではない。
require 'thread' class LocalBarrier def initialize(n) @n = n @waits = Queue.new end def sync if @waits.length == @n - 1 until (@waits.empty?) do @waits.pop.wakeup end else @waits.push(Thread.current) Thread.stop end end end