それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

rubyでやってみた。『増補改訂版Java言語で学ぶデザインパターン入門マルチスレッド編』まとめ

『増補改訂版Java言語で学ぶデザインパターン入門マルチスレッド編』を読んだ。


Javaマルチスレッドはすごいと。Java見直した。がrubyもしゅごい

Single Threaded Execution - この橋を渡れるのは、たった一人 
Immutable - 壊したくとも、壊せない 
Guarded Suspension - 用意できるまで、待っててね 
Balking - 必要なかったら、やめちゃおう 
Producer-Consumer - わたしが作り、あなたが使う 
Read-Write Lock - みんなで読むのはいいけれど、読んでる間は書いちゃだめ 
Thread-Per-Message - この仕事、やっといてね 
Worker Thread - 仕事が来るまで待ち、仕事が来たら働く 
Future - 引換券を、お先にどうぞ 
Two-Phase Termination - 後片付けしてから、おやすみなさい 
Thread-Specific Storage - スレッドごとのコインロッカー 
Active Object - 非同期メッセージを受け取る、能動的なオブジェクト 
まとめ - マルチスレッドプログラミングのパターン・ランゲージ
http://www.hyuki.com/dp/dp2.html

Rubyで解釈して、面倒だが、理解のため書き直していった。

rubyのマルチスレッド

  • I/Oメリットは享受できる。
  • スレッド切り替えはRubyでも重い処理の部類。
  • 移植性が高い。(Os依存は考えなくて良い
  • ネイティブスレッド・・まぁ、諦めろ

rubyでマルチスレッドする際のポイント

http://d.hatena.ne.jp/takuya_1st/20101123/1290497445

rubyの添付パッケージが便利だ。

添付ライブラリ

Ruby Reference Manual

  • マルチスレッド・同期
  • thread Mutex, Queue などのスレッド関連ユーティリティ
    • timeout タイムアウトを行うメソッド timeout
    • monitor モニタライブラリ (並行処理プリミティブ)
    • mutex_m Mutexのモジュール版
    • sync Mix-inにより再入可能なreader/writerロック機能を提供するライブラリ
    • thwait thread synchronization class

スレッドの作り方

継承
class MyThread < Thread
end
MyThread.new
ブロック
Thread.new(a){|arg|
 
}

rubyは継承よりブロックを渡す方を使うべき。

スレッドセーフ

mutex
m = Mutex.new
m.synchronize{

}

スレッドのWait

1:threadパッケージ mutex, ConditionVariable
require 'thread'
@m = Mutex.new
@cv = ConditionVariable.new
while ( self.ready? == false) do  @cv.wait(@m) end
2:添付パッケージmonitorを使う

スレッドの同期機構としてのモニター機能を提供するクラスです。 また同じスレッドから何度も lock できる Mutex としての機能も提供します。

require 'monitor'

buf = []
mon = Monitor.new
empty_cond = mon.new_cond

# consumer
Thread.start do
  loop do
    buf.synchronize do
      empty_cond.wait_while { buf.empty? } #ここでWait。Rubyらしい書き方で良い感じ。
      print buf.shift
    end
  end
end

# producer
while line = ARGF.gets
  buf.synchronize do
    buf.push(line)
    empty_cond.signal  #ここでnotify
  end
end
http://www.ruby-lang.org/ja/man/html/Monitor.html

かならずjoinする。

mainスレッドが終了すると、他のスレッドも終了するので、メインスレッドは他のスレッドを待つようにすること。

2010-11-25 追記

abort_on_exception

スレッド内部のエラーは検知されない*1ので、abort_on_exception をつける。スレッドがなんか変なときはとりあえずつけてみたら吉。

最後に

@hyuki先生。とっても丁寧でポイントが分かりやすい解説でした。Rubyで書くときに「まとめ」がとても参考になりました。ありがとうございます。数学ガール乱択アルゴリズム楽しみにしています。

*1:joinしないスレッド例外の場合