c++ - 如何在同一个线程上使用同一个互斥锁锁定两次?

标签 c++ mutex

我有这个类(简化):

// thing.h

#include <mutex>

class Thing
{
public:
    void process();
    void inner();

private:
    std::mutex lock;
};

// thing.cpp

#include "Thing.h"

using namespace std;

void Thing::process()
{
    lock_guard<mutex> locking(lock);

    inner();
}

void Thing::inner()
{
    lock_guard<mutex> locking(lock);
}

如果我调用进程,我会得到一个异常:

Microsoft C++ exception: std::system_error at memory location 0x006FF16C.

在同一线程中锁定同一锁会导致此异常。我怎么能毫无异常(exception)地做到这一点?我考虑过添加一个标志:

volatile bool alreadyLocked;

内部更改为:

void Thing::inner()
{
     if (!alreadyLocked)
     {
         lock_guard<mutex> locking(lock);
         alreadyLocked = true;
         ...something magic happens here...
         alreadyLocked = false;
     }
}

但是这感觉很脆弱......有没有正确的方法来做到这一点?

最佳答案

首先,volatile变量不是线程安全的。您必须使用 std::atomic<T>拥有线程安全的变量。 volatile与线程安全无关。

要解决您的问题,您可以使用 std::recursive_mutex ,可以从同一个线程多次锁定/解锁。

来自cppreference:

A calling thread owns a recursive_mutex for a period of time that starts when it successfully calls either lock or try_lock. During this period, the thread may make additional calls to lock or try_lock. The period of ownership ends when the thread makes a matching number of calls to unlock.

When a thread owns a recursive_mutex, all other threads will block (for calls to lock) or receive a false return value (for try_lock) if they attempt to claim ownership of the recursive_mutex.


此外,请考虑重构您的代码,以便不需要两次锁定互斥量。改进您的设计可能会避免这个问题。

关于c++ - 如何在同一个线程上使用同一个互斥锁锁定两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46767423/

相关文章:

c++ - 为什么这行得通? C中的字符指针

c++ - 如何使用 C API 创建嵌套的 Lua 表

c - 为什么此代码返回意外结果? (条件变量)

algorithm - 难以理解彼得森的算法

python - 在 Python 中正确使用互斥锁

c++ - 如何将命令行参数转换为 int?

c++ - 在使用聚合初始化时是否可以在 map 中执行 no-copy emplace?

c++ - 将字符串从一个 C++ 程序发送到另一个程序并等待响应

c++ - 在这种情况下有什么正确的方法来实现锁定?

c - 互斥体初始化 -(UNIX)