2016-11-23 62 views
2

我写了一个简单的代码,其中我使用unique_lock并解锁互斥锁,而不是调用锁本身的解锁。当第一个线程进入临界区并调用my_mutex.unlock()时,许多其他线程一起进入临界区。在与unique_lock关联的互斥锁中调用解锁会导致未定义的行为

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

这是怎么发生的?在由unique_lock持有的互斥体上调用解锁是否是错误的?谢谢!

回答

4

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

从cppreference.com调用std::mutex::unlock时:

互斥量必须执行的当前线程被锁定,否则,行为是不确定的。

的解决方案是不执行上互斥明确解锁。按照预期,让std::unique_lock在销毁后自行解锁。

对于需要在销毁前释放锁的情况,请使用std::unique_lock::unlock,这将允许安全销毁。或者,您可以简单地插入额外的范围,例如

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

谢谢!其实我在我的实际代码中没有本地互斥。我将更新问题中的代码。 – kwadhwa