c++ - 标准 C++ 中的共享递归互斥锁

标签 c++ multithreading c++11 mutex c++17

有一个shared_mutex为 C++17 计划的类(class)。和shared_timed_mutex已经在 C++14 中了。 (谁知道他们为什么按这个顺序出现,但无论如何。)然后有一个 recursive_mutexrecursive_timed_mutex从 C++11 开始。我需要的是一个 shared_recursive_mutex。我是否遗漏了标准中的某些内容,还是我必须再等三年才能获得标准版本?

如果目前没有这样的设施,那么仅使用标准 C++ 来简单(第一优先)和高效(第二优先)实现这样的功能是什么?

最佳答案

Recursive 互斥体的属性使用术语 owner 操作,如果 shared_mutex 没有明确定义:多个线程可能具有 .lock_shared() 同时调用。

假设 owner 作为线程调用 .lock()(不是 .lock_shared()!),递归共享互斥锁的实现可以可以简单地从 shared_mutex 派生:

class shared_recursive_mutex: public shared_mutex
{
public:
    void lock(void) {
        std::thread::id this_id = std::this_thread::get_id();
        if(owner == this_id) {
            // recursive locking
            count++;
        }
        else {
            // normal locking
            shared_mutex::lock();
            owner = this_id;
            count = 1;
        }
    }
    void unlock(void) {
        if(count > 1) {
            // recursive unlocking
            count--;
        }
        else {
            // normal unlocking
            owner = std::thread::id();
            count = 0;
            shared_mutex::unlock();
        }
    }

private:
    std::atomic<std::thread::id> owner;
    int count;
};

字段 .owner 需要声明为 atomic,因为在 .lock() 方法中,它会在没有保护并发访问的情况下进行检查。

如果你想递归调用 .lock_shared() 方法,你需要维护 所有者 map ,并且应该使用一些额外的互斥锁来保护对该 map 的访问。

允许具有事件 .lock() 的线程调用 .lock_shared() 使实现更加复杂。

最后,允许线程提前.lock_shared() 锁定到 .lock()no-no,因为当两个线程尝试执行该推进时,可能会导致死锁。


同样,recursive shared mutex 的语义非常脆弱,所以最好不要使用它。

关于c++ - 标准 C++ 中的共享递归互斥锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36619715/

相关文章:

c++ - 我可以访问我的对象的 'base part' 就好像它是它自己的对象一样吗?

c++ - GCC 和 MinGW (C++) 之间奇怪的输出差异

c++ - 为什么这个模板总是评估为 false_type?

c++ - 如何在容器中指定模板化别名的泛型类型

multithreading - 线程是否立即启动

c++ - 为什么在使用 std::bind 时复制构造函数被调用两次?

c++ - 错误 :"error LNK2019: unresolved external symbol"

c++ - 如果旧工作已经完成,如何开始新工作?

multithreading - 在多线程函数中声明后不久释放指针

java - 哪些方法可以减少 JDBC 线程暂停?