是否将 unique_lock 用于可以由 lock_guard 完成的任务较慢?
Posted
技术标签:
【中文标题】是否将 unique_lock 用于可以由 lock_guard 完成的任务较慢?【英文标题】:Is using unique_lock for a task that can be acomplished by lock_guard slower? 【发布时间】:2013-10-24 16:52:20 【问题描述】:我对@987654321@ 存在的原因感到困惑。是吗:
-
比
unique_lock
更简单的界面?
比unique_lock
性能更好?
还有别的吗?
【问题讨论】:
【参考方案1】:lock_guard
可以用一个状态单元来实现:一个指针或对它已锁定的Mutex
类型的引用。
unique_lock
必须保持该状态,并且知道当前是否已锁定,因为unique_lock
可以有一个未锁定的Mutex
。这意味着它必须至少有一个 bool
的额外状态。
lock_guard
在获取和释放Mutex
时提供了一个零 开销的 RAII 锁定/解锁包装器。基本上,lock_guard
意味着避免使用 RAII 处理 Mutex
上的锁的理由为零。
unique_lock
只能达到零开销,前提是编译器可以确信您仅以可以使用 lock_guard
的方式使用它(即,构造它,然后销毁它,而不是摆弄它)。
除了这些效率参数之外,看到lock_guard
的程序员知道它会持续到作用域结束,而无需检查作用域中的代码。看到unique_lock
的程序员必须检查变量的所有使用以了解是否是这种情况。
但以上只是一半的原因。
另一半是因为 C++11 的大部分线程库是基于 boost
库的,它已经实现了一个大部分独立于平台的线程库。 Boost 同时具有lock_guard
和unique_lock
,其语义与C++11 版本几乎相同。
所以当boost
线程库被标准化时,无论是在哪里都被带入了,并且没有人消除它们。
【讨论】:
【参考方案2】:您几乎在这里回答了自己的问题 - 1) 和 2) 都是很好的理由。 std::lock_guard 是一个简单的作用域锁定对象。互斥体获取超时等特性增加了互斥体原语的复杂性,增加了执行操作所需的时间和互斥体争用的可能性。那么为什么要为不需要的东西买单呢?
带有或不带有超时的“try_locking”是否是好的设计是另一个问题;比如线程取消,一个 C++11 没有实现的破碎设计。
【讨论】:
以上是关于是否将 unique_lock 用于可以由 lock_guard 完成的任务较慢?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 std::condition_variable 采用 unique_lock 而不是 lock_guard? [复制]
使用std::lock 和 std::unique_lock来起先swap操作
第一次锁定和创建 lock_guard(adopt_lock) 和创建 unique_lock(defer_lock) 和锁定有啥区别?