C++11 等价于 boost shared_mutex
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14306797/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++11 equivalent to boost shared_mutex
提问by Haatschii
Is there a C++11 equivalent for the boost::shared_mutex
. Or another solution to handle a multiple reader / single writer situation in C++11?
是否有 C++11 等效的boost::shared_mutex
. 还是在 C++11 中处理多读取器/单写入器情况的另一种解决方案?
回答by Howard Hinnant
I tried but failed to get shared_mutex
into C++11. It has been proposed for a future standard. The proposal is here.
我尝试过但未能shared_mutex
进入 C++11。它已被提议作为未来的标准。提案在这里。
Edit: A revised version (N3659) was acceptedfor C++14.
编辑:C++14接受了修订版 (N3659) 。
Here is an implementation:
这是一个实现:
http://howardhinnant.github.io/shared_mutex
http://howardhinnant.github.io/shared_mutex
回答by Sean Cline
Simple... There isn't one. There is no standard C++ implementation of a readers-writerlock.
很简单……没有。读写锁没有标准的 C++ 实现。
But, you have a few options here.
但是,您在这里有几个选择。
- You are left at your own devices to make your own readers-writer lock.
- Use a platform-specific implementation such as Win32's, POSIX's, or Boost'sas you mention.
- Don't use one at all -- use a mutexwhich already exists in C++11.
Going with #1and implementing your own is a scary undertaking and it is possible to riddle your code with race conditions if you don't get it right. There is a reference implemenationthat may make the job a bit easier.
使用#1并实现你自己的是一项可怕的任务,如果你没有做对,就有可能用竞争条件来破解你的代码。有一个参考实现可能会使工作更容易一些。
If you want platform independent code or don't want to include any extra libraries in your code for something as simple as a reader-writer lock, you can throw #2out the window.
如果您想要独立于平台的代码或不想在您的代码中包含任何额外的库来实现诸如读写锁之类的简单功能,您可以将#2扔出窗口。
And, #3has a couple caveats that most people don't realize: Using a reader-writer lock is often less performant, and has more difficult-to-understand code than an equivalent implementation using a simple mutex. This is because of the extra book-keeping that has to go on behind the scenes of a readers-writer lock implementation.
而且,#3有几个大多数人没有意识到的警告:使用读写锁通常性能较低,并且与使用简单互斥锁的等效实现相比,代码更难以理解。这是因为必须在读写锁实现的幕后进行额外的簿记。
I can only present you your options, really it is up to you to weigh the costs and benefits of each and pick which works best.
我只能向您展示您的选择,实际上由您来权衡每种选择的成本和收益,然后选择最有效的方式。
Edit:C++17 now has a shared_mutex
type for situations where the benefits of having multiple concurrent readers outweigh the performance cost of the shared_mutex
itself.
编辑:C++17 现在有一种shared_mutex
类型,用于具有多个并发读取器的好处超过shared_mutex
自身性能成本的情况。
回答by Philipp Cla?en
No, there is no equivalent for boost::shared_mutex
in C++11.
不,boost::shared_mutex
在 C++11 中没有等价物。
Read/writer locks are supported in C++14 or later, though:
但是,C++14 或更高版本支持读/写锁:
- C++14 added
std::shared_timed_mutex
- C++17 added
std::shared_mutex
- 添加了 C++14
std::shared_timed_mutex
- 添加了 C++17
std::shared_mutex
The difference is that std::shared_timed_mutex
adds additional timing operations. It implements the SharedTimedMutex concept, which is an extension of the simpler TimedMutex conceptimplemented by std::shared_mutex
.
不同之处在于std::shared_timed_mutex
增加了额外的计时操作。它实现了SharedTimedMutex 概念,它是由 实现的更简单的TimedMutex 概念的扩展std::shared_mutex
。
Keep in mind that acquiring a lock for a read/writer mutex is more costly than acquiring a normal std::mutex
. As a consequence, a read/writer mutex will not improve the performance if you have frequent, but short read operations. It is better suited for scenarios were read operations are frequent and expensive. To quote from Anthony Williams' post:
请记住,为读/写互斥锁获取锁比获取普通std::mutex
. 因此,如果您有频繁但短暂的读取操作,则读/写互斥锁不会提高性能。它更适合于读取操作频繁且昂贵的场景。引用安东尼威廉姆斯的帖子:
The cost of locking a shared_mutex is higher than that of locking a plain std::mutex, even for the reader threads. This is a necessary part of the functionality --- there are more possible states of a shared_mutex than a mutex, and the code must handle them correctly. This cost comes in both the size of the object (which in both your implementation and my POSIX implementation includes both a plain mutex and a condition variable), and in the performance of the lock and unlock operations.
Also, the shared_mutex is a point of contention, and thus not scalable. Locking a shared_mutex necessarily modifies the state of the mutex, even for a read lock. Consequently, the cache line holding the shared_mutex state must be transferred to whichever processor is performing a lock or unlock operation.
If you have a lot of threads performing frequent, short read operations, then on a multiprocessor system this can lead to a lot of cache ping-pong, which will considerably impact the performance of the system. In this case, you may as well adopt the simpler design of just using a plain mutex, as the readers are essentially serialized anyway.
If the reads are not frequent, then there is no contention, so you don't need to worry about concurrent readers, and a plain mutex will suffice for that scenario anyway.
If the read operations are time consuming, then the consequence of this contention is less visible, since it is dwarfed by the time spent whilst holding the read lock. However, performing time consuming operations whilst holding a lock is a design smell.
In the vast majority of cases, I think that there are better alternatives to a shared_mutex. These may be a plain mutex, the atomic support of shared_ptr, the use of a carefully constructed concurrent container, or something else, depending on context.
锁定 shared_mutex 的成本高于锁定普通 std::mutex 的成本,即使对于读取器线程也是如此。这是功能的必要部分——shared_mutex 的可能状态比 mutex 多,代码必须正确处理它们。这个成本来自对象的大小(在你的实现和我的 POSIX 实现中都包括一个普通的互斥锁和一个条件变量),以及锁定和解锁操作的性能。
此外,shared_mutex 是一个争论点,因此不可扩展。锁定 shared_mutex 必然会修改互斥锁的状态,即使是读锁也是如此。因此,必须将保持 shared_mutex 状态的缓存行转移到执行锁定或解锁操作的任何处理器。
如果您有很多线程执行频繁、短时间的读取操作,那么在多处理器系统上这可能会导致大量缓存乒乓,这将显着影响系统的性能。在这种情况下,您也可以采用仅使用普通互斥锁的更简单的设计,因为无论如何读取器本质上都是序列化的。
如果读取不频繁,则不存在争用,因此您无需担心并发读取器,无论如何,普通互斥锁就足够了。
如果读操作很耗时,那么这种争用的后果就不那么明显了,因为它与持有读锁所花费的时间相形见绌。然而,在持有锁的同时执行耗时的操作是一种设计味道。
在绝大多数情况下,我认为有更好的替代 shared_mutex 的方法。这些可能是普通的互斥锁、shared_ptr 的原子支持、精心构造的并发容器的使用,或者其他东西,具体取决于上下文。