C++ boost::unique_lock 与 boost::lock_guard

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6731027/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:35:44  来源:igfitidea点击:

boost::unique_lock vs boost::lock_guard

c++boostlocking

提问by Guillaume07

I don't well understand the difference betweeen these two lock classes. In boost documentation it is said, boost::unique_lockdoesn't realize lock automatically.

我不太明白这两个锁类之间的区别。在 boost 文档中说,boost::unique_lock不会自动实现锁定。

Does it mean that the main difference between unique_lockand lock_guardis that with unique_lockwe must call explicitly the lock()function ?

这是否意味着之间的主要区别unique_lock,并lock_guard是用unique_lock我们必须显式调用lock()功能?

回答by mkaes

First to answer your question. No you don't need to call lock on a unique_lock. See below:

先回答你的问题。不,您不需要在 unique_lock 上调用锁。见下文:

The unique_lock is only a lock class with more features. In most cases the lock_guard will do what you want and will be sufficient.
The unique_lock has more features to offer to you. E.g a timed wait if you need a timeout or if you want to defer your lock to a later point than the construction of the object. So it highly depends on what you want to do. BTW: The following code snippets do the same thing.

unique_lock 只是一个具有更多功能的锁类。在大多数情况下, lock_guard 会做你想做的,并且足够了。
unique_lock 为您提供了更多功能。例如,如果您需要超时,或者如果您想将锁定推迟到比对象的构造更晚的时间点,则可以进行定时等待。所以这在很大程度上取决于你想做什么。顺便说一句:下面的代码片段做同样的事情。

boost::mutex mutex;
boost::lock_guard<boost::mutex> lock(mutex);

boost::mutex mutex;
boost::unique_lock<boost::mutex> lock(mutex);

The first one can be used to synchronize access to data, but if you want to use condition variables you need to go for the second one.

第一个可用于同步数据访问,但如果您想使用条件变量,则需要使用第二个。

回答by jayadev

The currently best voted answer is good, but it did not clarify my doubt till I dug a bit deeper so decided to share with people who might be in the same boat.

目前投票得最好的答案是好的,但在我深入挖掘之前它并没有澄清我的疑问,所以决定与可能在同一条船上的人分享。

Firstly both lock_guardand unique_lockfollows the RAII pattern, in the simplest use case the lock is acquired during construction and unlocked during destruction automatically. If that is your use case then you don't need the extra flexibility of unique_lockand lock_guardwill be more efficient.

首先两者lock_guardunique_lock遵循RAII图案,在最简单的情况下使用该锁施工期间获得并自动销毁过程中解锁。如果这是您的用例,那么您不需要额外的灵活性unique_lock并且lock_guard会更高效。

The key difference between both is a unique_lockinstance doesn't need to always own the mutex it is associated with while in lock_guardit owns the mutex. This means unique_lockwould need to have an extra flag indicating whether it owns the lock and another extra method 'owns_lock()' to check that. Knowing this we can explain all extra benefits this flags brings with the overhead of that extra data to be set and checked

两者之间的主要区别在于unique_lock实例不需要始终拥有与其关联的互斥锁,而在lock_guard其中拥有互斥锁。这意味着unique_lock需要有一个额外的标志来指示它是否拥有锁和另一个额外的方法“owns_lock()”来检查它。知道这一点,我们可以解释这个标志带来的所有额外好处,以及要设置和检查的额外数据的开销

  1. Lock doesn't have to taken right at the construction, you can pass the flag std::defer_lockduring its construction to keep the mutex unlocked during construction.
  2. We can unlock it before the function ends and don't have to necessarily wait for destructor to release it, which can be handy.
  3. You can pass the ownership of the lock from a function, it is movableand not copyable.
  4. It can be used with conditional variables since that requires mutex to be locked, condition checked and unlocked while waiting for a condition.
  1. Lock 不必在构造时正确使用,您可以std::defer_lock在构造过程中传递标志以在构造过程中保持互斥锁处于解锁状态。
  2. 我们可以在函数结束之前解锁它,而不必等待析构函数释放它,这可以很方便。
  3. 您可以从函数传递锁的所有权,它是可移动的,不可复制的
  4. 它可以与条件变量一起使用,因为这需要在等待条件时锁定互斥锁、条件检查和解锁。

回答by Mihails Strasuns

Their implementation can be found under path .../boost/thread/locks.hpp - and they are sitting just one next to other :) To sum things short:

他们的实现可以在路径 .../boost/thread/locks.hpp 下找到 - 他们只是一个挨着另一个:) 总结一下:

lock_guardis a short simple utility class that locks mutex in constructor and unlocks in destructor, not caring about details.

lock_guard是一个简短的简单实用程序类,它在构造函数中锁定互斥锁并在析构函数中解锁,不关心细节。

unique_lockis a bit more complex one, adding pretty lot of features - but it still locks automatically in constructor. It is called unique_lock because it introduces "lock ownership" concept ( see owns_lock() method ).

unique_lock有点复杂,添加了很多功能 - 但它仍然在构造函数中自动锁定。它被称为 unique_lock 是因为它引入了“锁所有权”的概念(参见 owns_lock() 方法)。

回答by Sean

If you're used to pthreads(3):

如果你习惯pthreads(3)

  • boost::mutex= pthread_mutex_*
  • boost::unique_lock= pthread_rwlock_*used to obtain write/exclusive locks (i.e. pthread_rwlock_wrlock)
  • boost::shared_lock= pthread_rwlock_*used to obtain read/shared locks (i.e. pthread_rwlock_rdlock)
  • boost::mutex= pthread_mutex_*
  • boost::unique_lock=pthread_rwlock_*用于获取写/排他锁(即pthread_rwlock_wrlock
  • boost::shared_lock=pthread_rwlock_*用于获取读/共享锁(即pthread_rwlock_rdlock

Yes a boost::unique_lockand a boost::mutexfunction in similar ways, but a boost::mutexis generally a lighter weight mutex to acquire and release. That said, a shared_lockwith the lock already acquired is faster (and allows for concurrency), but it's comparatively expensive to obtain a unique_lock.

是的 aboost::unique_lock和一个boost::mutex函数以类似的方式,但 aboost::mutex通常是一个重量较轻的互斥锁来获取和释放。也就是说,shared_lock已经获得锁的a更快(并允许并发),但获得 .a 的成本相对较高unique_lock

You have to look under the covers to see the implementation details, but that's the gist of the intended differences.

您必须深入了解实现细节,但这就是预期差异的要点。



Speaking of performance: here's a moderately useful comparison of latencies:

说到性能:这里有一个比较有用的延迟比较:

http://www.eecs.berkeley.edu/%7Ercs/research/interactive_latency.html

http://www.eecs.berkeley.edu/%7Ercs/research/interactive_latency.html

It would be nice if I/someone could benchmark the relative cost of the different pthread_* primitives, but last I looked, pthread_mutex_*was ~25us, whereas pthread_rwlock_*was ~20-100us depending on whether or not the read lock had been already acquired (~10us) or not (~20us) or writer (~100us). You'll have to benchmark to confirm current numbers and I'm sure it's very OS specific.

如果我/某人可以对不同 pthread_* 原语的相对成本进行基准测试,那就太好了,但最后我看到的pthread_mutex_*是 ~25us,而pthread_rwlock_*~20-100us 取决于是否已经获取了读锁(~10us ) 或不 (~20us) 或作家 (~100us)。您必须进行基准测试以确认当前数字,而且我确信它是特定于操作系统的。

回答by Aleksei Petrenko

I think unique_lock may be also used when you need to emphasize the difference between unique and shared locks.

我认为当您需要强调唯一锁和共享锁之间的区别时,也可以使用 unique_lock 。