Ruby には本当のマルチスレッド機能がありますか? 質問する

Ruby には本当のマルチスレッド機能がありますか? 質問する

私はRubyの「協調的」スレッドについて知っています。緑の糸複数の CPU コアを処理に利用するために、アプリケーションで実際の「OS レベル」のスレッドを作成するにはどうすればよいでしょうか。

ベストアンサー1

Jörg の 2011 年 9 月のコメントを更新しました

ここでは、Ruby プログラミング言語と、Ruby プログラミング言語の特定の実装の特定のスレッド モデルという、2 つの非常に異なるものを混同しているようです。現在、Ruby プログラミング言語には約 11 種類の異なる実装があり、それぞれ非常に異なる独自のスレッドモデルがあります。

(残念ながら、これら 11 の実装のうち実際に製品版で使用できるのは 2 つだけですが、年末までにその数はおそらく 4 つまたは 5 つに増えるでしょう。) (更新: 現在は MRI、JRuby、YARV (Ruby 1.9 のインタープリター)、Rubinius、IronRuby の 5 つです)。

  1. 最初の実装には実際には名前がないので、参照するのが非常に厄介で、非常に煩わしく、混乱を招きます。これはほとんどの場合「Ruby」と呼ばれますが、これは名前がない場合よりもさらに煩わしく、混乱を招きます。なぜなら、Ruby プログラミング言語の機能と特定の Ruby 実装との間で際限のない混乱が生じるからです。

「MRI」(「Matz の Ruby 実装」の略)、CRuby、または MatzRuby と呼ばれることもあります。

MRIはRubyスレッドをインタプリタ内でグリーンスレッドとして実装する残念ながら、これらのスレッドを並行してスケジュールすることはできず、一度に実行できるのは 1 つのスレッドだけです。

ただし、任意の数の C スレッド (POSIX スレッドなど) を Ruby スレッドと並行して実行できるため、外部の C ライブラリや独自のスレッドを作成する MRI C 拡張機能も並行して実行できます。

  1. 2番目の実装はヤルヴ(「Yet Another Ruby VM」の略)。YARVはRubyスレッドをPOSIXまたはWindows NTスレッドとして実装しますただし、グローバルインタープリタロック (GIL) を使用して、一度に 1 つの Ruby スレッドのみが実際にスケジュールされるようにします。

MRI と同様に、C スレッドは実際に Ruby スレッドと並行して実行できます

将来的には、GIL がより細かいロックに分割され、より多くのコードを実際に並列実行できるようになる可能性がありますが、それはまだ遠い将来のことであり、計画すらされていません。

  1. ルビー Rubyスレッドをネイティブスレッドとして実装するここで、JVM の場合の「ネイティブ スレッド」は、明らかに「JVM スレッド」を意味します。JRuby は、それらに対して追加のロックを課しません。したがって、それらのスレッドが実際に並列実行できるかどうかは、JVM によって異なります。一部の JVM は JVM スレッドを OS スレッドとして実装し、一部はグリーン スレッドとして実装します。(Sun/Oracle の主流 JVM は、JDK 1.3 以降、OS スレッドのみを使用しています)

  2. XRubyまたRubyスレッドをJVMスレッドとして実装する更新: XRuby は終了しました。

  3. アイアンルビー Rubyスレッドをネイティブスレッドとして実装するここで、CLR の場合の「ネイティブ スレッド」は明らかに「CLR スレッド」を意味します。IronRuby はそれらに対して追加のロックを課さないため、CLR がそれをサポートしている限り、それらは並列で実行されるはずです。

  4. Ruby.NETまたRubyスレッドをCLRスレッドとして実装する更新: Ruby.NETは終了しました。

  5. ルビニウス 仮想マシン内でRubyスレッドをグリーンスレッドとして実装するより正確に言うと、Rubinius VM は、非常に軽量で、非常に柔軟な並行性/並列性/非ローカル制御フロー構造をエクスポートします。これは「タスク"、およびその他のすべての並行性構造(このディスカッションのスレッドだけでなく、継続俳優およびその他の機能は、Tasks を使用して純粋な Ruby で実装されています。

Rubiniusは(現時点では)スレッドを並列にスケジュールすることはできませんが、それはそれほど大きな問題ではありません。Rubiniusはすでに複数のPOSIXスレッドで複数のVMインスタンスを並列に実行する、1つのRubiniusプロセス内で実行できます。スレッドは実際にはRubyで実装されているため、他のRubyオブジェクトと同様に、シリアル化して別のPOSIXスレッドの別のVMに送信できます。(これはBEAMと同じモデルです。アーランVMはSMP同時実行に使用します。すでにRubinius Actors 用に実装

更新: この回答の Rubinius に関する情報は、もう存在しない Shotgun VM に関するものです。「新しい」C++ VM は、複数の VM にまたがってスケジュールされたグリーン スレッド (つまり Erlang/BEAM スタイル) を使用せず、CLR、Mono、およびほぼすべての JVM で採用されているものと同様の、複数のネイティブ OS スレッド モデルを備えたより従来的な単一の VM を使用します。

  1. マクルビーYARVをObjective-CランタイムとCoreFoundation、Cocoaフレームワーク上に移植したものとして始まりました。現在ではYARVから大きく離れていますが、私の知る限りでは、現在でもYARVと同じスレッドモデルを共有します更新: MacRubyは Apple のガベージ コレクターに依存していますが、これは非推奨と宣言されており、MacOSX の以降のバージョンでは削除される予定です。MacRuby は死んでいます。

  2. 枢機卿は、Ruby実装です。パロット仮想マシンスレッドはまだ実装されていないが、実装されたら、おそらく次のように実装されるだろう。パロットスレッド更新: Cardinal は非常に非アクティブ/死んでいるようです。

  3. マグレブは、Ruby実装です。GemStone/S Smalltalk VMGemStone/S がどのスレッド モデルを使用するのか、MagLev がどのスレッド モデルを使用するのか、さらにはスレッドがすでに実装されているかどうか (おそらく実装されていない) についても情報がありません。

  4. ホットルビーは、完全な Ruby 実装ではありません。JavaScript の YARV バイトコード VM の実装です。HotRuby はスレッドをサポートしていません (まだ?)。サポートしたとしても、JavaScript が真の並列処理をサポートしていないため、並列で実行することはできません。ただし、HotRuby の ActionScript バージョンがあり、ActionScript は実際に並列処理をサポートする可能性があります。更新: HotRuby は終了しました。

残念ながら、これら 11 個の Ruby 実装のうち、実際に製品化可能なのは MRI と JRuby の 2 つだけです。

したがって、真の並列スレッドが必要な場合、JRuby が現在のところ唯一の選択肢です。ただし、これは悪い選択肢ではありません。JRuby は実際には MRI よりも高速で、より安定していると言えます。

それ以外の場合、「古典的な」Rubyの解決策は、並列処理のためにスレッドではなくプロセスを使用することです。Rubyコアライブラリには、ProcessモジュールとともにProcess.fork方法これにより、別のRubyプロセスをフォークすることが非常に簡単になります。また、Ruby標準ライブラリには分散 Ruby (dRuby / dRb)ライブラリを使用すると、Ruby コードを同じマシン上だけでなくネットワーク上の複数のプロセスに簡単に分散できます。

おすすめ記事