boost::unique_lock vs boost::lock_guard
boost::unique_lock vs boost::lock_guard
我不太明白这两个锁类之间的区别。在boost文档中说,boost::unique_lock
不自动实现锁。
这是否意味着unique_lock
和lock_guard
之间的主要区别在于unique_lock
必须显式调用lock()
函数?
首先回答你的问题。不,你不需要在unique_lock上调用lock。
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);
第一个可以用来同步对数据的访问,但是如果你想使用条件变量,你需要使用第二个。
目前最好的投票答案是好的,但它并没有澄清我的疑问,直到我深入挖掘了一点,所以决定与可能在同一条船的人分享。
首先,lock_guard
和unique_lock
都遵循RAII模式,在最简单的用例中,锁在构造期间获得,在销毁期间自动解锁。如果这是你的用例,那么你不需要unique_lock
的额外灵活性,lock_guard
将更有效。
两者之间的关键区别是unique_lock
实例不需要总是拥有与之关联的互斥锁,而在lock_guard
中它拥有互斥锁。这意味着unique_lock
需要有一个额外的标志来指示它是否拥有锁和另一个额外的方法'owns_lock()'来检查。知道了这一点,我们就可以解释这个标志带来的所有额外的好处,以及要设置和检查的额外数据的开销
- 锁不必在构造时立即采取,您可以在构造期间传递标志
std::defer_lock
以保持互斥锁在构造期间解锁。 - 我们可以在函数结束之前解锁它,而不必等待析构函数释放它,这很方便。你可以从一个函数传递锁的所有权,它是可移动而不是可复制。
- 它可以与条件变量一起使用,因为这需要在等待条件时锁定互斥锁,检查条件并解锁。
它们的实现可以在path…/boost/thread/locks.hpp下找到-它们只是一个挨着另一个坐着:)总之:
lock_guard是一个简短的实用程序类,在构造函数中锁定互斥锁,在析构函数中解锁,不关心细节。
unique_lock稍微复杂一点,增加了相当多的特性——但它仍然在构造函数中自动锁定。之所以叫unique_lock,是因为它引入了"锁所有权"的概念(参见owns_lock()方法)。
如果你已经习惯了pthreads(3)
:
-
boost::mutex
=pthread_mutex_*
-
boost::unique_lock
=pthread_rwlock_*
用于获取写/排他锁(即pthread_rwlock_wrlock
) -
boost::shared_lock
=pthread_rwlock_*
用于获取读/共享锁(即pthread_rwlock_rdlock
)
是的,boost::unique_lock
和boost::mutex
函数的方式相似,但boost::mutex
通常是一个更轻的互斥锁来获取和释放。也就是说,已经获得锁的shared_lock
更快(并且允许并发),但是获得unique_lock
的成本相对较高。
您必须深入了解实现细节,但这是预期差异的要点。
说到性能,这里有一个比较有用的延迟:
http://www.eecs.berkeley.edu/%7Ercs/research/interactive_latency.html如果我/某人可以对不同pthread_*原语的相对成本进行基准测试就好了,但是最后我看,pthread_mutex_*
是~25us,而pthread_rwlock_*
是~20-100us,这取决于读锁是否已经获得(~10us)或是否(~20us)或写(~100us)。你必须通过基准测试来确认当前的数字,我相信这是非常特定于操作系统的。
我认为当您需要强调唯一锁和共享锁之间的区别时,也可以使用unique_lock
- 理解boost::asio-async_read在无需读取内容时的行为
- boost::进程间消息队列引发错误
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- cmake如何在fedora工作站中找到boost静态库包
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- Boost Graph Library,修复节点大小
- 什么是"#include <boost/functional/hash.hpp> "?
- 基于boost的程序的静态链接——zlib问题
- C++:如何在CLion IDE中安装Boost
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何在boost beast http请求中设置http头
- Boost Spirit,获取迭代器内部语义动作
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- boost::asio如何生成多个协同程序,然后加入它们
- 当我尝试使用 sstream 和分面将 Boost Time_duration转换为字符串时,我没有得到所需的格式
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- std::lock() equivalent for boost::shared_mutex?
- 调用 boost::lock 析构函数的效果?
- 错误:调用'boost::shared_lock<boost::shared_mutex>::shared_lock(const Lock&)'没有匹配函数