我想使用新的标准线程而不是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。当前的副本要求手动执行,而另一个则要求标准化读取/写入器锁定。 –