2013-01-14 4 views
16

私はしばらくの間ReaderWriterLockSlimを使用していましたが、これまでのところ私のニーズを満たしていました。私のアプリケーションを微調整し続けると、ReaderWriterLockSlimが私の使用事例ではあまり最適ではないことが分かります。読者に有利なReaderWriterLockSlimはありますか?

ドキュメント(および私の経験)によれば、読者よりもライターが優先されます(つまり、読者とライターがキューに入れられたとき、ライターが優先されます)。しかし、私は読者に有利なものが必要です。私はそのようなコンポーネントの副作用を理解しています(特に作家の飢えの問題)。

誰かが指摘できる実績のある同等品がありますか?ありがとう。

+3

コードが存在しないことは決して証明できません。しかし、そうは思わない。ショッピングに関する質問は避けてください。 –

+0

読み取りを優先したい場合は、内部リストを更新されたクローンで置き換えてみてください。あなたのコードはロックフリーですが、アップデートには少し重いです。 – jgauffin

+1

ええ、jgauffinが示唆しているようにコピーでこれを解決できるかのように聞こえるかもしれません。あるいは、データ構造が安価なコピーでは大きすぎて書き込みバッファでは書き込みがそれほど頻繁ではない場合があります。次に、バッファをフラッシュする時間を上下にラッチすることによって、読み書きバランスを微調整できます。 –

答えて

6

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とカスタムロック用ライター飢餓):

Performance comparison

トンので、私は、ワークロードのループがコンパイラによって巻き出されていないことを確認しましたが、私は認識していないよ、他の落とし穴があるかもしれませんこれらの測定値は塩の穀物である。テストのソースコードはhereです。

+0

素晴らしいと非常に詳細な答え!大変感謝しています - 私は見ていきます。 –