C++ std::锁定保护或std::范围锁定?
C++17引入了一个新的锁类,名为 从文档中判断,它看起来类似于已经存在的C++ std::锁定保护或std::范围锁定?,c++,multithreading,locking,c++17,C++,Multithreading,Locking,C++17,C++17引入了一个新的锁类,名为 从文档中判断,它看起来类似于已经存在的std::lock\u guard类 区别是什么?我应该在什么时候使用它?一个重要的区别是std::scoped_lock有一个可变构造函数使用多个互斥锁。这允许以避免死锁的方式锁定多个互斥锁,就像使用了std::lock一样 { // safely locked as if using std::lock std::scoped_lock<std::mutex, std::mutex> loc
std::lock\u guard
类
区别是什么?我应该在什么时候使用它?一个重要的区别是
std::scoped_lock
有一个可变构造函数使用多个互斥锁。这允许以避免死锁的方式锁定多个互斥锁,就像使用了std::lock
一样
{
// safely locked as if using std::lock
std::scoped_lock<std::mutex, std::mutex> lock(mutex1, mutex2);
}
{
//像使用std::lock一样安全地锁定
std::作用域锁定(mutex1,mutex2);
}
之前,您必须使用std::lock
以一种安全的方式来锁定多个互斥锁
范围锁的添加使其更易于使用,并避免了相关错误。可以考虑<代码> STD::std::scoped_lock
的单参数情况可以实现为一种专门化,因此您不必担心可能的性能问题
GCC 7已经支持可以看到的std::scoped_lock
有关更多信息,您可能需要阅读范围锁定
是lock\u-guard
的严格高级版本,它一次锁定任意数量的互斥锁(使用与std::lock
相同的死锁避免算法)。在新代码中,您应该只使用范围锁定
唯一仍然存在的原因是兼容性。它不能被删除,因为它在当前代码中使用。此外,证明了它的定义是不可取的(从一元到变量),因为C++也是一种可观察的,因此也会发生变化(但有点技术上的原因)。
std::scoped_lock
的存在意味着,在c++17之前使用std::lock
的大多数情况下,现在可以使用std::scoped_lock
编写,错误的可能性更小,这只能是一件好事
迟交的答复,主要是针对:
你可以考虑<代码> STD::LoCuxGueG/<代码>。< /P>
对于只需要锁定一个互斥锁的常见情况,
std::lock\u guard
有一个比scoped\u lock
更安全的API
例如:
{
std::scoped_lock lock; // protect this block
...
}
上面的代码段可能是一个意外的运行时错误,因为它编译后完全不执行任何操作。编码员的意思可能是:
{
std::scoped_lock lock{mut}; // protect this block
...
}
现在它锁定/解锁mut
如果在上述两个示例中使用了lock\u guard
,则第一个示例是编译时错误,而不是运行时错误,第二个示例的功能与使用作用域锁定的版本相同
因此,我的建议是使用最简单的工具:
lock\u guard
如果您需要在整个范围内只锁定一个互斥锁
scoped_lock
如果需要锁定数量不完全为1的互斥锁
unique\u lock
如果需要在块的范围内解锁(包括与条件变量一起使用)
此建议并不意味着应重新设计作用域锁定
,使其不接受0个互斥锁。存在有效的用例,scoped_lock
需要接受可变模板参数包(可能为空)。空箱子不应该锁任何东西
这就是为什么lock\u-guard
没有被弃用的原因scoped_lock
和unique_lock
可能是lock\u guard
功能的超集,但这一事实是一把双刃剑。有时,类型不能做的事情(本例中为默认构造)同样重要。此外,由于类模板参数的推导,您甚至不必列出可锁定的类型。@Nicolas:没错,但这也适用于lock\u guard
。但是它确实使保护类更容易使用。作用域锁定是C++17,只有当它是C++17时,兼容性是它存在的一个特别好的原因。我也强烈反对任何绝对主义者的主张,即“你应该永远只使用”当墨水仍然按照这个标准干燥时。解释为什么scoped_lock
不是lock_guard
的严格高级版本。保持lock\u-guard
的原因不仅仅是兼容性!仅仅10分钟就回答了你自己的问题。你真的不知道吗?@Walter当我在委员会上提出这个问题时,答案是“什么都不知道”。可能是某个算法的退化情况,这正是正确的。或者,可能有足够多的人在打算锁定某个东西时意外地锁定了任何东西,这是一个常见的问题。我真的不确定。@HowardHinnant:scoped\u lock lk;//锁定作用域中的所有互斥锁
。LGTM@KerrekSB:scoped_lock lk
是范围锁定lk的新缩写代码>。没有互斥体。所以你是对的。;-)精彩洞察,感谢分享。:)
{
std::scoped_lock lock; // protect this block
...
}
{
std::scoped_lock lock{mut}; // protect this block
...
}