0

ロックステートメントを使用せず、パフォーマンス上の理由から volatile と Interlocked のみを使用して、高性能のスレッドセーフコンポーネントを実装しています。

クラスに、スレッドセーフなインスタンスを含む揮発性の参照型メンバーがあります。このインスタンスは、いくつかの操作に対してのみスレッド セーフであり、別の操作ではスレッド セーフではありません。そのため、およびパフォーマンス上の理由から、元のインスタンスを更新する代わりに新しいインスタンスを作成することを好む場合があり、特にロックステートメントを使用しないため、実際に高速に動作します。

そのため、volatile メンバーはいつでも別のインスタンスに置き換えることができます。volatile キーワードを使用すると、マルチスレッド環境で問題が発生しなくなります。

もちろん、これは非常にうまく機能しますが、唯一の問題は、古いインスタンスのガベージ コレクションです。コンポーネントのパフォーマンスをテストしたところ、リリースされたインスタンスのガベージ コレクションに時間がかかりすぎていることがわかりました。

今、古いインスタンスをリサイクルする方法を探しています。問題は、このインスタンスをまだ使用している別のスレッドが存在する可能性があり、このインスタンスを誰も使用していないことを保証する方法 (ロックなし) が見つからないため、交換時に古いインスタンスを取得してその状態をリセットすることができないことです。もう。

ロックステートメントなしで古いインスタンスを使用するスレッドがないことをどのように保証できますか? (volatile と Interlocked が推奨されます)

ありがとう。

4

4 に答える 4

2

ここで実装しようとしているのは、参照カウントに非常によく似ています (COM を覚えていますか?)。おそらく、インクリメント/デクリメントを使用してこれを行うことができます-参照カウンターを参照のすぐ隣に置いてください。

この手法の唯一の問題は、オブジェクトの利用者が適切にオブジェクトを使用することに依存していることです。これにより、コードが非常に壊れやすくなります。

別の質問は、ロックの主なパフォーマンスの問題は、ロック自体ではなく、それが意味するメモリバリアであるということです。ポイントは、揮発性変数へのすべてのアクセスが同じことを行うということです。言い換えれば、ロックを揮発性変数に置き換えても何も得られないと思います

于 2009-12-22T22:49:21.073 に答える
1

問題は、任意のスレッドがオブジェクトへの参照をスタックに取り、それに対して必要なことを実行できることです。全体的なロックを使用せずに、スレッドセーフでない操作でこれを防ぐ方法はありません。

一般に、.NET ガベージ コレクターを操作するべきではありません。GC に時間がかかる理由を突き止め、そのために最適化することをお勧めします (最初からあまり多くのインスタンスを作成しないでください。スレッドセーフな方法でインスタンスを再利用しようとするのではなく、多数のインスタンスを作成する O(n^2) 操作?)。

于 2009-12-22T22:38:09.273 に答える
0

オブジェクトを死から蘇らせることができます。つまり、オブジェクトが完成すると、実際にオブジェクトを再び生き返らせることができます。これには、ライフサイクルのこの時点では、それらへの参照がないという利点があります。そうしないと、そもそもファイナライズに適用できなかったでしょう。詳細については、この記事の「Ressurection」の章を参照してください。

さて、それが本当にあなたにパフォーマンスを買うのか、それともそれをする価値があるのか​​、私にはわかりません;-)

于 2009-12-23T05:54:05.980 に答える
0

マルチスレッドアプリケーションでオブジェクトを操作しても安全かどうかを教えてくれる何かが存在するかどうかを尋ねています。それがロックの定義です。.NET によって提供される構造を使用しても十分に高速でない場合は、より高速に実行される準拠言語に変更することを検討する必要があります。

于 2009-12-22T22:47:39.670 に答える