我一直在使用ReaderWriterLockSlim一段時間,它已經滿足了我的需求。當我繼續微調我的應用程序時,我發現ReaderWriterLockSlim
對我的用例來說稍微不太理想。根據文檔(以及我的經驗),它支持作者優先於讀者(即當讀者和作者排隊時,作者將獲得偏好)。但是,我需要一個有利於讀者的等價物。我理解這種組件的副作用(特別是作者飢餓問題)。是否有ReaderWriterLockSlim等價於讀者?
有人可以指出任何生產就緒等價物嗎?謝謝。
我一直在使用ReaderWriterLockSlim一段時間,它已經滿足了我的需求。當我繼續微調我的應用程序時,我發現ReaderWriterLockSlim
對我的用例來說稍微不太理想。根據文檔(以及我的經驗),它支持作者優先於讀者(即當讀者和作者排隊時,作者將獲得偏好)。但是,我需要一個有利於讀者的等價物。我理解這種組件的副作用(特別是作者飢餓問題)。是否有ReaderWriterLockSlim等價於讀者?
有人可以指出任何生產就緒等價物嗎?謝謝。
根據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和作家飢餓自定義鎖):
我確信,工作量循環不被編譯器展開,但也可能有其他陷阱我不知道的,因此T用一粒鹽做這些測量。測試的源代碼是here。
很好很詳細的答案!非常感謝 - 我會看看。 –
無法確切地證明代碼的缺失。但是,不,這是不太可能的。請避免提出購物問題。 –
如果你想支持讀取,爲什麼不用一個更新的克隆替換內部列表?您的代碼將被鎖定,但更新時會稍重一些。 – jgauffin
是的,這聽起來像你可以用jgauffin所建議的副本來解決這個問題,或者如果數據結構對於廉價的副本來說太大了,那麼寫入緩衝區的寫入就不那麼頻繁。然後,您可以通過上下調整緩衝區的刷新時間來調整讀/寫餘額。 –