C++17 引入了一个名为 std::scoped_lock
的新锁类。
从文档来看,它看起来类似于已经存在的 std::lock_guard
类。
有什么区别,我应该什么时候使用它?
原文由 Stephan Dollberg 发布,翻译遵循 CC BY-SA 4.0 许可协议
C++17 引入了一个名为 std::scoped_lock
的新锁类。
从文档来看,它看起来类似于已经存在的 std::lock_guard
类。
有什么区别,我应该什么时候使用它?
原文由 Stephan Dollberg 发布,翻译遵循 CC BY-SA 4.0 许可协议
这是 C++ Concurrency in Action 的示例和引用:
friend void swap(X& lhs, X& rhs)
{
if (&lhs == & rhs)
return;
std::lock(lhs.m, rhs.m);
std::lock_guard<std::mutex> lock_a(lhs.m, std::adopt_lock);
std::lock_guard<std::mutex> lock_b(rhs.m, std::adopt_lock);
swap(lhs.some_detail, rhs.some_detail);
}
对比
friend void swap(X& lhs, X& rhs)
{
if (&lhs == &rhs)
return;
std::scoped_lock guard(lhs.m, rhs.m);
swap(lhs.some_detail, rhs.some_detail);
}
std::scoped_lock
的存在意味着您在 c++17 之前使用std::lock
的大多数情况现在可以使用std::scoped_lock
编写,潜力较小对于错误,这只能是一件好事!原文由 Chen Li 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
迟到的答案,主要是为了回应:
对于需要恰好锁定一个互斥锁的常见情况,
std::lock_guard
具有比scoped_lock
更安全的 API。例如:
上面的代码片段很可能是一个意外的运行时错误,因为它编译然后什么都不做。编码器可能的意思是:
现在 它锁定/解锁
mut
。如果在上面的两个示例中使用了
lock_guard
,则第一个示例是编译时错误而不是运行时错误,第二个示例具有与使用scoped_lock
的版本相同的功能---
.所以我的建议是使用最简单的工具来完成这项工作:
lock_guard
如果您需要在整个范围内准确锁定 1 个互斥锁。scoped_lock
如果您需要锁定多个不完全为 1 的互斥锁。unique_lock
如果您需要在块范围内解锁(包括与condition_variable
一起使用)。该建议 并不 意味着 应该重新设计
scoped_lock
以不接受 0 互斥锁。存在有效的用例,需要scoped_lock
接受可能为空的可变参数模板参数包。空壳 不应 锁定任何东西。这就是为什么
lock_guard
不被弃用的原因。scoped_lock
和unique_lock
可能是lock_guard
功能的超集,但事实是一把双刃剑。有时,类型 不会 做什么(在这种情况下为默认构造)同样重要。