MSDNによると、ReaderWriterLockSlimはライターに有利です。これは、キューに読者とライターがいる場合、ライターが優先権を得ることを意味します。
これは、リーダーの飢餓を引き起こす可能性があります。これを再現するテストコードはhereです。 私は、書き込みがスレッドコンテキストスイッチを含む長い操作である場合にのみ、飢餓が起こると想定しています。少なくともそれは常に私のマシン上に再現されるので、私が間違っているかどうか教えてください。
一方、.net 2.0のReaderWriterLockは、パフォーマンスの低下を犠牲にして、リーダーやライターの飢餓状態を引き起こしません。 Hereは、飢餓状態が発生していないことを示すために、前のサンプルのコードが変更されています。
あなたの質問に戻る - それはあなたがRWロックから必要な機能に依存します。 再帰ロック、例外処理、タイムアウト - に最も一致します。上記のすべてをサポートするRWロックで、ReaderWriterLockが役に立つでしょう。
first readers-writers problemを記述するwiki記事のコードを採用することもできますが、上記のすべての必要な機能を手動で実装する必要があり、実装にはライター飢餓の問題があります。
ロックコアは、おそらく次のようになります
class AutoDispose : IDisposable
{
Action _action;
public AutoDispose(Action action)
{
_action = action;
}
public void Dispose()
{
_action();
}
}
class Lock
{
SemaphoreSlim wrt = new SemaphoreSlim(1);
int readcount=0;
public IDisposable WriteLock()
{
wrt.Wait();
return new AutoDispose(() => wrt.Release());
}
public IDisposable ReadLock()
{
if (Interlocked.Increment(ref readcount) == 1)
wrt.Wait();
return new AutoDispose(() =>
{
if (Interlocked.Decrement(ref readcount) == 0)
wrt.Release();
});
}
}
3つの実装のパフォーマンスを比較すると、3リーダーと3つのライター・スレッドを使用して、メモリ内の長いブロック操作を使用して操作が(のためのリーダ飢餓を生成する簡単な使用しますRWLockSlimとカスタムロック用ライター飢餓):
トンので、私は、ワークロードのループがコンパイラによって巻き出されていないことを確認しましたが、私は認識していないよ、他の落とし穴があるかもしれませんこれらの測定値は塩の穀物である。テストのソースコードはhereです。
コードが存在しないことは決して証明できません。しかし、そうは思わない。ショッピングに関する質問は避けてください。 –
読み取りを優先したい場合は、内部リストを更新されたクローンで置き換えてみてください。あなたのコードはロックフリーですが、アップデートには少し重いです。 – jgauffin
ええ、jgauffinが示唆しているようにコピーでこれを解決できるかのように聞こえるかもしれません。あるいは、データ構造が安価なコピーでは大きすぎて書き込みバッファでは書き込みがそれほど頻繁ではない場合があります。次に、バッファをフラッシュする時間を上下にラッチすることによって、読み書きバランスを微調整できます。 –