Ruby-不変オブジェクト
-
03-07-2019 - |
質問
Rubyで書かれた、いくつかのインスタンス変数を共有する高度にマルチスレッド化されたアプリを持っています。これらの変数への書き込みはまれ(1%)ですが、読み取りは非常に一般的です(99%)。 これらのスレッドが常に関連する最新の値を表示するようにするための最良の方法(あなたの意見または慣用的なRubyの方法のいずれか)とは何ですか?ここまでのアイデアは次のとおりです(私はこれをオーバーホールする前にあなたの入力をお願いします):
- これらの変数のいずれかを読み書きする前に最も使用されるロックを持っている(から) Java並行性の実践)。この欠点は、コード内に多くの
synchronize
ブロックを配置することであり、それを回避する簡単な方法がわかりません。 - Rubyの
freeze
メソッドを使用します(こちらを参照)同様に面倒に見え、最初のオプションが提供する同期の利点を私に与えません。
これらのオプションはどちらも非常に似ているように見えますが、うまくいけばそこにいる人はもっと良いアイデアを持っているでしょう(または、これらのアイデアの1つについてよく議論できる)。また、操作の途中でオブジェクトが破損したり変更されたりしないようにオブジェクトを不変にすることもできますが、Rubyを自分で呼び出してこの質問は、オブジェクトは非常に変更可能であると主張しているようです。
解決
これを行うには、ロックを使用するのが最も適切な方法です。このテーマについては、ジムウェイリッヒによる次のプレゼンテーションをご覧ください:すべてのRubyistがスレッドについて知っておくべきこと。
また、これらの変数を変更したいので、オブジェクトを凍結してもここでは役に立ちません。それらを所定の位置に固定すると、これ以上の修正はこれらに適用されなくなります(したがって、書き込みの1%は機能しなくなります)。
他のヒント
自分で使用したことはありませんが、データフロー。すべての変数を1回だけ書き込みます。
リーダー/ライターロックは、明確に定義されたソリューションの一般的な問題です。
そしてそれの多くの実装があります:
読み取り/書き込みごとにロックをかけたくない
Mutexを使用して、共有状態へのアクセスを同期する必要があります。これを回避する方法は本当にありません。
最新のマルチコアマシンでは、メモリへのアクセス方法やメモリアクセスとキャッシュの相互作用について推測することはできません。