【问题标题】:Is there a `shared_lock_guard` and if not, what would it look like?是否有`shared_lock_guard`,如果没有,它会是什么样子?
【发布时间】:2016-08-27 20:22:28
【问题描述】:

我想在课堂上使用std::mutex,但注意到它不可复制。我在我的图书馆的底层,所以有这种行为似乎是一个糟糕的主意。

我在std::mutex 上使用了std::lock_guard,但似乎没有shared_lock_guard,最好提供写锁专用行为。这是我自己的疏忽还是微不足道的实施?

【问题讨论】:

  • 也许你需要这个:std::shared_lock
  • 这听起来像是一个严重的 XY 问题/设计缺陷。如果你有一个类级别的互斥锁,请不要复制它。
  • "我在我的图书馆的底层,所以有这种行为似乎是一个糟糕的主意。"互斥体通常不应该存在于"图书馆的底层”。至少,不是你建议的方式。这听起来像是您正在尝试对实用程序类的互斥锁访问。这通常是个坏主意。
  • @πάνταῥεῖ 这就是我要做的。但是关于std::shared_lock_guardstd::shared_mutex::shared_lock 提供范围保护的问题仍然有效。
  • 如果您真的想要非作用域锁定(例如,在多个线程之间共享),请进入std::shared_ptr<std::lock_guard<Mutex>> 的领域以及与之相关的所有乐趣,包括导致死锁的内存泄漏。我个人更希望看到您的 XY 问题的 X 部分,希望我们能对此有所帮助。

标签: c++ c++11 locking c++14 mutex


【解决方案1】:

通过C++14,您可以使用std::shared_lockstd::unique_lock 来实现读/写锁定:

class lockable
{
public:
    using mutex_type = std::shared_timed_mutex;
    using read_lock  = std::shared_lock<mutex_type>;
    using write_lock = std::unique_lock<mutex_type>;

private:
    mutable mutex_type mtx;

    int data = 0;

public:

    // returns a scoped lock that allows multiple
    // readers but excludes writers
    read_lock lock_for_reading() { return read_lock(mtx); }

    // returns a scoped lock that allows only
    // one writer and no one else
    write_lock lock_for_writing() { return write_lock(mtx); }

    int read_data() const { return data; }
    void write_data(int data) { this->data = data; }
};

int main()
{
    lockable obj;

    {
        // reading here
        auto lock = obj.lock_for_reading(); // scoped lock
        std::cout << obj.read_data() << '\n';
    }

    {
        // writing here
        auto lock = obj.lock_for_writing(); // scoped lock
        obj.write_data(7);
    }
}

注意:如果您有C++17,那么您可以使用std::shared_mutex 代替mutex_type

【讨论】:

  • 我不太确定 OP 是否真的要求 RW 锁。
  • @πάνταῥεῖ 也许吧。但我想不出他还有什么意思。
【解决方案2】:

它还不是 C++ 标准的一部分,但你可以在 boost 中找到实现示例。

template<typename SharedMutex>
class shared_lock_guard
{
private:
    SharedMutex& m;

public:
    typedef SharedMutex mutex_type;
    explicit shared_lock_guard(SharedMutex& m_):
        m(m_)
    {
        m.lock_shared();
    }
    shared_lock_guard(SharedMutex& m_,adopt_lock_t):
        m(m_)
    {}
    ~shared_lock_guard()
    {
        m.unlock_shared();
    }
};

它需要符合 SharedMutex 概念的互斥类; std::shared_mutex 是提议的 C++17 标准的一部分,而 boost 已经有一段时间了:boost::shared_mutex

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-12
    • 2014-01-20
    • 1970-01-01
    相关资源
    最近更新 更多