(共享)C ++中的互斥锁

我看过一个共享互斥锁的示例:

class MyData {
    std::vector<double> data_;
    mutable shared_mutex mut_;   // the mutex to protect data_;

public:
    void write() {
        unique_lock<shared_mutex> lk(mut_);
        // ... write to data_ ...
    }

    void read() const {
        shared_lock<shared_mutex> lk(mut_);
        // ... read the data ...
    }
};

自然,我本来会写:

public:
    void write() {
        mut_.lock();
        // ... write to data_ ...
        mut_.unlock();
    }

    void read() const {
        mut_.lock_shared();
        // ... read the data ...
        mut_.unlock_shared();
    }
};

我的方法也正确吗?在示例中使用的内容与我使用的内容之间是否有区别?另外,一个相对于另一个有优势吗?谢谢!

X00400 回答:(共享)C ++中的互斥锁

我的方法也正确吗?

考虑如果互斥锁的锁定与解锁之间的代码引发异常,将会发生什么情况:

void write() {
    mut_.lock();
    // <-- exception is thrown here
    mut_.unlock();
}

然后,互斥锁将保持锁定状态。

一个人比另一个人有优势吗?

是的,unique_lock<>跟在RAII idiom之后,因此在发生异常的情况下,互斥锁的解锁是自动处理的(即,由其析构函数进行处理):

void write() {
    unique_lock<shared_mutex> lk(mut_);
    // <-- exception is thrown
}

在创建unique_lock<shared_mutex>对象– lk之后发生异常的情况下–将调用其析构函数,然后如果其被锁定,则将其解锁相关联的互斥体(请记住std::unique_lockstd::lock_guard不同,它并不总是拥有相关互斥锁的锁的所有权–请参见std::defer_lockstd::unique_lock::unlock())。

总而言之,对于lock_guard / unique_lock / shared_lock,在发生异常或将成员函数置于不同执行路径的情况下,不需要您进行特殊处理。 / p>

,

通常避免使用原始互斥锁,而推荐使用RAII版本unique_lock(),这在两种情况下更安全:

  • 例外
  • 过早归还

通常避免使用原始指针,而推荐使用RAII版本的智能指针:unique_ptr或shared_ptr。

无论哪种情况,RAII版本都可以确保互斥量(或指针)在超出范围时始终被释放。

本文链接:https://www.f2er.com/2745043.html

大家都在问