Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::锁定保护或std::范围锁定?_C++_Multithreading_Locking_C++17 - Fatal编程技术网

C++ std::锁定保护或std::范围锁定?

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

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> 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
       ...
    }