我想使用新的標準線程而不是boost:threads,但我注意到舊的shared_mutex不可用。替換這個功能並給我一個多讀者,單寫作者鎖定會是一個好建議?C++ 11線程的RW鎖
回答
std::shared_mutex
將成爲C++ 14標準庫的一部分。它並沒有使它成爲C++ 11,因爲沒有時間制定提案並進行徹底討論。
雖然你仍然可以使用boost::shared_mutex
。在Windows下,如果您使用的是Windows Vista或更高版本,則可以使用Slim Read-Write Locks,它們針對速度和內存消耗進行了優化。
您應該看看堆棧溢出問題「C++11 equivalent to boost shared_mutex」,特別是以下鏈接的電子郵件對話:http://permalink.gmane.org/gmane.comp.lib.boost.devel/211180(它解釋了C++ 11委員會對批准shared_mutex的阻力)。還有關於Joe Duffy的博客的以下實驗:http://www.bluebytesoftware.com/blog/2009/02/12/ReaderwriterLocksAndTheirLackOfApplicabilityToFinegrainedSynchronization.aspx。
每當您考慮讀寫器鎖定時,請問自己以下6個問題。如果你可以對其中的任何一個回答「否」,那麼讀寫器鎖將會讓你的程序變得更糟,而不是更好。
- 是我的共享對象
const
?在我的生活中,我看到shared_mutex
更多不正確的用法,而不是正確的用法。要正確使用shared_mutex
,必須爲,您可以在讀者關鍵部分內聲明您的共享對象const
,而不會有任何編譯器投訴。 「消費者」是而不是等同於「完全不改變數據結構的人」。 - 我的關鍵部分真的很長嗎?鎖定一個shared_mutex是比鎖定普通互斥鎖要貴得多。您必須在關鍵部分有批次以彌補鎖獲取/釋放的增加開銷。
- 應該我的關鍵部分是那麼長?你應該問自己,你是否真的需要在關鍵部分做所有這些工作。通常會有一大堆準備工作和/或工作來按摩圍繞
const
調用共享對象的返回對象。大部分不在從第一次使用共享對象到最後一次使用共享對象的數據依賴路徑上的額外工作都可以移出關鍵部分。 - 鎖定爭用真的是我的表現問題嗎?即使你的關鍵部分很長,你也應該確保鎖定爭用實際上是你的性能問題。如果您沒有遇到嚴重的鎖爭用,那麼切換到讀寫器鎖並不會爲您購買任何東西。
- 我可以通過切換到更細粒度鎖定方案來減少鎖爭用嗎?您是否使用單個鎖來保護多個對象?你可以給每個對象自己的鎖嗎?
- 讀者與作家的比例是明顯是大於1:1嗎?即使你的關鍵部分很長,鎖定競爭是一個嚴重的問題,閱讀者與作者之間的比例需要非常高,才能從讀者/作家鎖定獲得任何好處。數量取決於硬件原子指令的成本以及特定實現的質量。 (Joe Duffy發現,在他的機器上,他需要一個20:1左右的讀者比例:作家讓讀者/作家鎖定勝利。)
儘管Joe Duffy需要仔細閱讀該頁面。由於_one_特定類型的rw-lock(在.NET中)以某種方式執行,所以一般來說對rw-lock沒有太大的影響。 rw-lock不會比關鍵段對象慢,並且它不會使用CAS操作。有太多的變化,例如它不公平(或者,它可能不得不)。根據情況,rw-lock可能比互斥鎖效率更高(2-3個數量級)。 R/W的比率也很有趣... – Damon
... 1至20的比例也很有趣。這並不是特別特別的東西。使用錯誤的工具執行任務肯定會給出平庸的結果。這就像抱怨說在隨機訪問時使用'std :: list'表現不佳,或者在前面插入數百萬個元素時'std :: vector'表現不佳。如果你的閱讀不會超過你的寫作數量,那麼當然rw-lock不會贏(可能是一個損失)。但那是使用了錯誤的工具。 – Damon
Duffy的每0.25毫秒(= 250,000ns)一個請求的例子也是一個很好的例子。這是一個「完全零擁擠」的情況。即使考慮CAS操作的過度成本(通常小於25ns),在這種情況下,我覺得很有趣。現代CPU不受每秒執行4000次原子操作的挑戰。 – Damon
- 1. 使用使用C++ 11線程庫C++ 11個線程
- 2. C++ 11叮噹的線程
- 3. C++ 11 VS2012中的線程/互斥鎖實現 - 斷言觸發
- 4. C#線程死鎖
- 5. C++線程死鎖
- 6. C++ 11線程vs升級線程
- 7. C++ 11線程與.Net線程?
- 8. C++ 11線程等待
- 9. C++ 11線程未加入
- 10. C++ 11線程隊列
- 11. C++ 11線程分離
- 12. C++ 11動態線程池
- 13. C++ 11線程錯誤
- 14. C讀者作家線程鎖解鎖
- 15. C#線程 - 鎖對象
- 16. C#線程鎖定失敗
- 17. 鎖內新線程 - c#
- 18. C#線程和鎖定
- 19. 主線程鎖定在C#
- 20. 鎖定資源(線程,C++)
- 21. 在C中鎖定線程#
- 22. C#多線程 - 鎖定
- 23. Visual C++與C + + 11和線程支持
- 24. 用於C++ 11的線程,用新的
- 25. C++ 11的std ::線程週期
- 26. 如何終止C++ 11中的線程?
- 27. std ::非void函數的線程(C++ 11)
- 28. 在C++ 11線程中等效的WAIT_ABANDONED
- 29. C++ 11 std ::線程奇怪的行爲
- 30. 基於C++的線程類庫11
我認爲更好的重複將是https://stackoverflow.com/q/14306797/783510。當前的副本要求手動執行,而另一個則要求標準化讀取/寫入器鎖定。 –