2013-01-14 94 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文章中的代碼,但當然您需要手動實現上述所有必需的功能,並且實現將具有writer-starvation問題。

鎖芯也許可以是這樣的:

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

我確信,工作量循環不被編譯器展開,但也可能有其他陷阱我不知道的,因此T用一粒鹽做這些測量。測試的源代碼是here

+0

很好很詳細的答案!非常感謝 - 我會看看。 –

相關問題