C++ 使用互斥锁时,unique_lock有什么特殊用途?

C++ 使用互斥锁时,unique_lock有什么特殊用途?,c++,c++11,threadpool,mutex,stdthread,C++,C++11,Threadpool,Mutex,Stdthread,我不太清楚为什么std::unique_lock比普通锁更有用。我正在查看的代码中的一个示例是: {//aquire lock std::unique_lock<std::mutex> lock(queue_mutex); //add task tasks.push_back(std::function<void()>(f)); }//release lock 这些代码片段是否完成了相同的任务 这些代码片段完成了同样

我不太清楚为什么
std::unique_lock
比普通锁更有用。我正在查看的代码中的一个示例是:

{//aquire lock

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

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

}//release lock
这些代码片段是否完成了相同的任务

这些代码片段完成了同样的任务吗

没有


第一个将释放块末端的锁,无论块是什么。如果关键部分以
中断
继续
返回
转到
异常或我忘记的任何其他类型的非局部跳转退出,则第二个将不会在结束时释放锁。

使用
唯一锁
提供了在面对更改和错误时的弹性

  • 如果更改流以添加中间“跳转”(
    return
    例如)
  • 如果抛出异常
在任何情况下,锁都会自动释放

另一方面,如果您试图手动执行此操作,则可能会错过一个案例。即使你现在不知道,以后的编辑可能会


注意:这是C++中的一个惯用的习惯用法,称为SBRM(Simulink Engand RealManagement),其中你可以使用一个清理动作来叠放,这样你就可以保证,除非崩溃/不优美的退出,否则它被执行。


它还显示了RAII(资源获取是初始化),因为
unique\u lock
的构造本身就获取了资源(这里是互斥锁)。尽管名称不同,该首字母缩写词也通俗地用于指销毁时的确定性释放,其涵盖范围比SBRM更广,因为它指的是所有类型的确定性释放,不仅仅是那些基于堆栈展开的调用。

考虑后一个示例中在
lock/unlock
调用之间引发的异常……一旦您理解了这个问题,下面的链接可能会让您感兴趣。打败我!我还要补充一点,std::unique_lock相对于RAII有显著的优势。假设在调用unlock()之前,互斥锁中的一个方法抛出。互斥锁可能永远无法解锁。std::unique_lock保证释放,即使在as std::mutex不会抛出的情况下抛出异常(因为必须手动调用unlock),第一种方法实际上实现了大多数人在编写第二种方法时所希望的。因此,在将来任何适用的情况下,总是选择使用
std::unique_lock
,这是否明智呢?@SyntacticFructose我会说是的。总的来说,它有点安全。@SyntacticFructose:在大多数情况下,一个简单的
std::lock\u-guard
就足够了。通常,最好使用最简单的类型来完成某项任务。
queue_mutex.lock();

//add task
//...

queue_mutex.unlock();