gpt4 book ai didi

c++ - scoped_lock 可以在读取模式下锁定 shared_mutex 吗?

转载 作者:IT老高 更新时间:2023-10-28 22:30:29 30 4
gpt4 key购买 nike

C++17 引入了 std::shared_mutexstd::scoped_lock。我现在的问题是,当它作为参数传递时,scoped_lock 将始终以独占(写入器)模式锁定共享互斥锁,而不是在共享(读取器)模式下。在我的应用程序中,我需要使用来自对象 src 的数据更新对象 dst。我想锁定 src 共享和 dst 独占。不幸的是,如果同时调用另一个带有 srcdst 切换的更新方法,这可能会导致死锁。所以我想使用 std::scoped_lock 的花哨的死锁避免机制。

我可以使用 scoped_lock 在独占模式下同时锁定 srcdst,但是这种不必要的严格锁定会在其他地方产生性能回退。但是,似乎可以将 srcshared_mutex 包装到 std::shared_lock 并与 一起使用scoped_lock:当scoped_lock在其锁定 Action 中调用shared_lock上的try_lock()时,后面会实际调用srcshared_mutex 上尝试_shared_lock(),这就是我需要的。

所以我的代码看起来很简单:

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???
}

在另一个(避免死锁)锁守卫中使用这样的(共享)锁守卫是否安全?

最佳答案

正如阅读了 C++ 标准库的实现代码的各种评论员所指出的:是的,使用包装在 std::shared_lock( ) 作为 std::scoped_lock() 的参数之一是安全的。

基本上,std::shared_lock 将所有对 lock() 的调用转发到互斥体上的 lock_shared()

std::shared_lock::lock -----------> mutex()->lock_shared(). // same for try_lock etc..

另一种可能的解决方案

std::shared_lock lk1(src.mutex, std::defer_lock);
std::unique_lock lk2(dst.mutex, std::defer_lock);
std::lock(lk1, lk2);

std::lock 是一个函数,它接受任意数量的 Lockable 对象并锁定所有对象(或异常中止,在这种情况下它们都将被解锁)。

std::scoped_lock 根据 cppreferencestd::lock 的包装器,增加了在其析构函数中对每个 Lockable 对象调用 unlock() 的功能。这里不需要添加的功能,因为 std::shared_lock lk1std::unique_lock lk2 也可以作为锁守卫,当它们的互斥锁退出时解锁范围。

编辑:各种澄清

关于c++ - scoped_lock 可以在读取模式下锁定 shared_mutex 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54641216/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com