unique_lock使用互斥锁有什么特殊用途?

Syn*_*ose 7 c++ mutex threadpool c++11 stdthread

我不太清楚为什么std::unique_lock<std::mutex>仅仅使用普通锁是有用的.我正在看的代码中的一个例子是:

{//aquire lock

        std::unique_lock<std::mutex> lock(queue_mutex);

        //add task
        tasks.push_back(std::function<void()>(f));

}//release lock
Run Code Online (Sandbox Code Playgroud)

为什么会偏爱

queue_mutex.lock();

//add task
//...

queue_mutex.unlock();
Run Code Online (Sandbox Code Playgroud)

这些代码片段完成同样的事情吗?

R. *_*des 20

[Do]这些代码片段完成了同样的事情吗?

没有.

无论块是什么,第一个将在块的末尾释放锁.第二个不会在月底解除锁定,如果关键部分与退出break,continue,return,goto,异常或任何其他种类的非本地跳是我忘记了的.

  • IOW,第一个实际上*做*大多数人在写第二个时所希望的. (5认同)
  • @SyntacticFructose:在大多数情况下,简单的`std :: lock_guard`应该足够了.使用最简单的类型来完成某项任务通常是个好主意. (2认同)

Mat*_* M. 5

unique_lock面对变化和错误,使用提供弹性.

  • 如果更改流程以添加中间"跳转"(return例如)
  • 如果抛出异常
  • ...

在任何情况下,锁都会自动释放.

另一方面,如果您尝试手动执行此操作,则可能会错过一个案例.即使你现在没有,稍后的编辑可能会.


注意:这是C++中常用的习惯用法,称为SBRM(Scoped Bound Resources Management),您可以将清理操作绑定到堆栈展开,这样您就可以确保,除非崩溃/不正常退出,否则执行它.

它还展示了RAII(资源获取是初始化),因为它unique_lock获取了资源(这里是互斥体).尽管它的名字,这个首字母缩略词也通俗地用于指破坏时的确定性释放,它涵盖了比SBRM更广泛的范围,因为它涉及所有类型的确定性释放,而不仅仅是基于堆栈展开的那些.