multithreading - 对与 unique_lock 关联的互斥体调用解锁会导致未定义的行为

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

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

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

为什么会发生这种情况?对 unique_lock 持有的互斥体调用解锁是否错误?谢谢!

最佳答案

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

调用 std::mutex::unlock 时来自 cppreference.com:

The mutex must be locked by the current thread of execution, otherwise, the behavior is undefined.

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

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

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

关于multithreading - 对与 unique_lock 关联的互斥体调用解锁会导致未定义的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40772628/

相关文章:

c# - Mono 中的非托管进程

java - 我可以访问 Java 中同步块(synchronized block)使用的锁吗?

c++ - 当我希望线程终止时,删除包含正在运行的线程的类是否可以/安全?

c++ - 如何安排这个多线程应用程序?

java - Android - 获取线程 ID - 使用此 SO 方法始终返回 0

C++11:在不知道其容器的情况下存储迭代器

c++ - 不确定查找功能在 CPP 中如何工作

c++ - boost::lexical_cast 对于 c++11 stoi、stof 和 family 是否是多余的?

c++ - 在二维 vector 中搜索数字序列的更快方法是什么?

c++ - 我想在C++中实现map,因为我无法检查 vector 大小并为我制作的 vector 提供值