18

私は時々Rubyをハッキングしてきましたが、大きなことやマルチスレッド化したことは何もしていません。MRIはグリーンスレッドのみをサポートし、JRubyはJVMを介したネイティブスレッドをサポートしていると聞きました。しかし、ブログやディスカッショングループで、「Railsはスレッドセーフではない」またはRuby自体はスレッドセーフではないというコメントに出くわしました。たとえば、requireステートメントに問題があると誰かがコメントしました。それは少し基本的に聞こえます。

並行性を適切に処理しないJavaアプリをたくさん見ましたが、時々悪夢を見ました:-)しかし、少なくとも、自分が何をしているのかを本当に知っていれば、Javaでスレッドセーフなアプリケーションを作成できます簡単ではありません)。

これはすべて非常に憂慮すべきことのように聞こえますが、誰かがもっと詳しく説明することはできますか?正確には何が問題であり、これが事実である場合、Railsはどのように機能するのでしょうか?競合状態やデッドロックなしで正しく機能するマルチスレッドRubyコードを記述できますか?JRubyとMRIの間で移植可能ですか、それともJVMネイティブスレッドを適切に利用するためにJVM固有のコードをハックする必要がありますか?

編集:

人々はレールスレッディングのもの(それ自体は素晴らしい)とグリーンスレッディング対ネイティブスレッディングにしか答えていないように見えるので、私は2つの質問をするべきでした。スレッドセーフに関するRubyのコア問題に関する私の懸念は、実際には対処されていません。場合によっては、requireに少なくとも(未解決の?)問題があるようです。

4

4 に答える 4

14

何よりもまず、Ruby 1.9 (最新の公式リリース)はネイティブ (カーネル) スレッドを使用するようになりました。以前のバージョンの Ruby では、グリーン スレッドが使用されていました。質問に簡潔に答えると、1.9 より前は、大小を問わず Ruby アプリケーションでスレッドが一般的に使用されることはありませんでした。それは、特に安全性や信頼性が低いためです。

バージョン 2.2 より前の Rails はスレッドセーフを目指していなかったため、これは特に問題ではありません。そのため、通常、複数のプロセス、データベース レコードのロック、 Starlingのようなメッセージ キューを使用して非同期処理を処理しています。これは一般に、Web アプリケーションをスケーリングするための非常に信頼性の高い方法であり (少なくとも正しくないマルチスレッド Java アプリケーションよりも信頼性が高い)、アプリケーションを複数のプロセッサやサーバーに横方向にスケーリングすることが容易になるという追加の利点があります。

あなたが言及した 'require' の問題が 1.9 の時点で解決されているかどうかはわかりませんが、新しいスレッドでライブラリを動的に要求している場合、保守性の問題が複数あることを謙虚に思います。

スレッドを完全に回避したい場合、Ruby 1.9はファイバーもサポートします。ファイバーは同時実行性に対してシェアード ナッシング アプローチを採用しており、私が収集したところによると、スレッドよりも一般的に記述と保守が容易です。性能数値はこちら.

于 2009-03-16T21:23:04.170 に答える
6

RubyConf2008からのJimWeirichのスピーチをご覧になることをお勧めします(非常に面白くて有益です:):

https://www.youtube.com/watch?v=fK-N_VxdW7g

これもいいです:

http://rubyconf2008.confreaks.com/summer-of-code-rails-thread-safety.html

于 2009-03-15T20:10:24.837 に答える
5

MRI の通常の解決策は、複数の Rails インスタンスを実行し、それぞれがリクエストを個別に処理することです。とにかく MRI はマルチスレッド化されていないため、その上で複数の Rails インスタンスを実行することはできません。これは、Rails が Ruby プロセスごとに 1 回読み込まれるため、メモリ ヒットが発生することを意味します。

JRuby はネイティブ スレッドをサポートしているため、単一の JVM で常に複数の Rails インスタンスを実行できます。しかし、Rails がスレッド セーフであるため、1 つに減らすことができます。つまり、メモリ使用量が少なくなり、JIT コンパイルが少なくなります。

Charles Nutter (JRuby) は素晴らしい要約を持っています。

于 2009-03-15T11:34:03.313 に答える
1

以前のポスターはRailsのケースをかなりうまくカバーしていたと思うので、そのようなことについては気にしません。

スレッド化されたRubyアプリケーションを作成することは確かに可能です。ルビースレッドに存在する問題のいくつかは、仮想マシンによって管理されているため、「グリーン」であるということです。現在、デフォルトのインタープリター(MRI)には、インタープリターが制御するすべてのスレッドで共有する必要がある真のシステムスレッドが1つだけあります。

これの欠点は、複数のプロセッサまたはコアを搭載したコンピュータを使用している場合、アプリケーションのスレッドを他のコアで実行できないことです。これは、サーバーや高性能アプリを実行している人々にとってはかなり大きな問題です。

インタプリタ固有のコードに関する質問については、そうは思いません。ちなみに、JRuby/JVMスレッドを処理するために特別なことをする必要はありません。

また、Rubyの並行性の状態をよく見るIgvitaに関するこの記事。

于 2009-03-16T04:10:32.217 に答える