在与unique_lock关联的互斥锁上调用unlock会导致未定义的行为

时间:2016-11-23 19:25:07

标签: multithreading c++11 std mutex critical-section

我写了一个简单的代码,我拿了一个unique_lock并解锁互斥锁,而不是在锁本身上调用unlock。当第一个线程进入临界区并调用my_mutex.unlock()时,许多其他线程一起进入临界区。

std::mutex my_mutex;
void sample() {
   std::unique_lock<std::mutex> lock(my_mutex);
   // Critical section
   my_mutex.unlock();
}

为什么会这样?在unique_lock持有的互斥锁上调用unlock是不对的?谢谢!

1 个答案:

答案 0 :(得分:4)

UB不是由使用std::mutex::unlock的显式解锁引起的,而是由退出作用域时std::unique_lock析构函数执行的第二次解锁引起的。

在致电std::mutex::unlock时来自cppreference.com:

  

必须通过当前执行线程锁定互斥锁,否则行为未定义。

解决方案是在互斥锁上执行显式解锁。相反,让std::unique_lock按照预期在销毁时解锁。

对于需要在销毁之前释放锁的情况,请使用std::unique_lock::unlock以便安全销毁。或者,您只需插入一个额外的范围例如

void sample() {
    // Before.
    {
        std::unique_lock<std::mutex> lock(my_mutex);
        // Critical section.
    }
    // After.
}