Kai*_*zke 15 c++ deadlock scoped-lock
C++ 17引入了std::shared_mutex和std::scoped_lock.我现在的问题是scoped_lock,当它作为参数传递而不是在共享(读取器)模式下时,它将始终以独占(写入)模式锁定共享互斥锁.在我的应用程序中,我需要dst使用来自对象的数据更新对象src.我想锁定src共享和dst独占.不幸的是,如果同时调用另一个带有src和dst切换的更新方法,则可能会出现死锁.所以我想使用花哨的死锁避免机制std::scoped_lock.
我可以使用scoped_lock锁定src和dst独占模式,但不必要的严格锁具有其他地方的性能退缩.然而,现在看来,这是可能的包裹src的shared_mutex进入std::shared_lock和使用,用scoped_lock:当scoped_lock其锁定在行动电话try_lock()上shared_lock,以后将实际调用try_shared_lock()上src的shared_mutex,而这正是我需要的.
所以我的代码看起来很简单:
struct data {
mutable std::shared_mutex mutex;
// actual data follows
};
void update(const data& src, data& dst)
{
std::shared_lock slock(src.mutex, std::defer_lock);
std::scoped_lock lockall(slock, dst.mutex);
// now can safely update dst with src???
}
Run Code Online (Sandbox Code Playgroud)
在另一个(死锁避免)锁定防护装置中使用这样的(共享)锁定防护装置是否安全?
正如阅读过C ++标准库的实现代码的各种注释者所指出的那样:是的,将a std::shared_mutex内的换行符std::shared_lock()用作to的参数之一std::scoped_lock()是安全的。
基本上,a std::shared_lock将所有呼叫转移lock()到lock_shared()互斥锁上。
std::shared_lock::lock -----------> mutex()->lock_shared(). // same for try_lock etc..
Run Code Online (Sandbox Code Playgroud)
另一种可能的解决方案
std::shared_lock lk1(src.mutex, std::defer_lock);
std::unique_lock lk2(dst.mutex, std::defer_lock);
std::lock(lk1, lk2);
Run Code Online (Sandbox Code Playgroud)
std::lock是一个函数,它接受任意数量的Lockable对象并锁定所有对象(或异常中止,在这种情况下它们将全部被解锁)。
std::scoped_lock根据cppreference的说明,它是的包装器std::lock,具有unlock()在其析构函数中调用每个Lockable对象的附加功能。这里不需要添加功能,因为std::shared_lock lk1和std::unique_lock lk2也可以用作锁定防护,当它们超出范围时可以解锁其互斥锁。
编辑:各种说明
| 归档时间: |
|
| 查看次数: |
618 次 |
| 最近记录: |