Ben*_* C. 4 c++ multithreading mutex thread-safety c++17
我看过一个共享互斥锁的例子:
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 ...
}
};
Run Code Online (Sandbox Code Playgroud)
我自然会写:
public:
void write() {
mut_.lock();
// ... write to data_ ...
mut_.unlock();
}
void read() const {
mut_.lock_shared();
// ... read the data ...
mut_.unlock_shared();
}
};
Run Code Online (Sandbox Code Playgroud)
我的方法也对吗?我使用的内容与示例中使用的内容之间有区别吗?另外,一个比另一个有优势吗?谢谢!
眠りネ*_*ネロク 11
我的方法也对吗?
考虑如果互斥锁锁定和解锁之间的代码抛出异常会发生什么:
void write() {
mut_.lock();
// <-- exception is thrown here
mut_.unlock();
}
Run Code Online (Sandbox Code Playgroud)
然后互斥锁保持锁定状态。
一个比另一个有优势吗?
是的,unique_lock<>遵循RAII idiom,因此在发生异常时会自动处理互斥锁的解锁(即,由其析构函数):
void write() {
unique_lock<shared_mutex> lk(mut_);
// <-- exception is thrown
}
Run Code Online (Sandbox Code Playgroud)
如果在创建unique_lock<shared_mutex>对象后发生异常– lk– 调用其析构函数,然后如果它被锁定,则解锁关联的互斥锁(请记住std::unique_lock,与 不同std::lock_guard,并不总是拥有关联互斥锁的所有权 – 请参阅std::defer_lock和std::unique_lock::unlock())。
综上所述,随着lock_guard/ unique_lock/ shared_lock,没有特殊的处理是从你身边在例外的情况下,或离开由不同的执行路径的成员函数时需要。
通常避免使用原始互斥锁,而使用 RAII 版本 unique_lock(),这在两种情况下更安全:
像原始指针一样,通常会避免使用 RAII 版本的智能指针:unique_ptr 或 shared_ptr。
无论哪种情况,RAII 版本都确保互斥锁(或指针)在超出范围时始终被释放。
| 归档时间: |
|
| 查看次数: |
793 次 |
| 最近记录: |