Rubyでマルチスレッド <Thread>
どうも、こんにちは。kazunyaaanです。
年は明けましたが、まだまだ、大雪が続いております...
マルチスレッドやマルチプロセス
Haswell世代にて物理18コアを達成したE5-2699v3など、マルチコア化が進む中、
マルチスレッド or マルチプロセスは重要なキーワードではないでしょうか?
そこで、数回にわたってRubyにおけるマルチスレッドプログラミングを取り扱っていこうかと思います。
Rubyにおけるマルチスレッド処理
RubyではThreadクラスを用いて、以下のように比較的簡単に"並列"処理を行うことができます。
a_thread = Thread.new do 5.times do |i| puts "#{i} : I am A." end end b_thread = Thread.new do 5.times do |i| puts "#{i} : I am B." end end a_thread.join b_thread.join
メインスレッド、a_thread、b_threadの3つのスレッドがプログラム実行中に存在し、 実行結果は、マルチスレッドで実行しているため毎回異なりますが、
0 : I am B. 1 : I am B. 2 : I am B. 3 : I am B. 0 : I am A. 4 : I am B. 1 : I am A. 2 : I am A. 3 : I am A. 4 : I am A.
のようになりますね。
Threadクラスを使ったRubyのプログラムは"並列"に処理をしていることが確認できるかと思います。
しかし、Rubyのスレッドはある時点に1つのスレッドを処理しているもので、複数コアでの並列処理はできていないのです。
(top
コマンド等で確認してみてください)
Rubyのスレッドに関する(メモ)
(~1.8) -> グリーンスレッド http://docs.ruby-lang.org/ja/1.8.7/doc/spec=2fthread.html
(1.9~) -> ネイティブスレッド http://docs.ruby-lang.org/ja/2.2.0/doc/spec=2fthread.html
2.2.0のThreadクラスの実装の一部を見てみると...
ネイティブスレッドを用いて実装されていますが、 現在の実装では Ruby VM は Giant VM lock (GVL) を有しており、同時に実行される ネイティブスレッドは常にひとつです。
となってるんですよね...
次回、そこらへんを見ていきます。では。