我写了一个简单的代码,我拿了一个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是不对的?谢谢!
答案 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.
}