【问题标题】:Getting a read-only version of an Arc<RwLock<Foo>>?获取 Arc<RwLock<Foo>> 的只读版本?
【发布时间】:2021-12-24 07:43:38
【问题描述】:

我有一个Arc&lt;RwLock&lt;Foo&gt;&gt;

有没有办法从中做出一些事情,RwLock 的 write() 不存在?即是否有某种形式的RLock,我可以从RwLock 制作。

用例:我有一个Foo。我的代码中不止一部分需要对 Foo 进行变异(因此是 RwLock),但我的大部分代码只能对 Foo 具有只读访问权限。

有没有办法做到这一点?或者没有RwLock有没有办法做到这一点?

【问题讨论】:

  • 只需从read返回LockGuard(甚至是包装好的Result
  • 如果没有具体的例子很难回答,但您可以尝试不使用RwLock,而是使用Arc::get_mut()
  • @ChayimFriedman 不幸的是,我在不同的线程中有多个 Arc&lt;RwLock&lt;Foo&gt;&gt; 的克隆。
  • @fadedbee,你需要在某个时候释放锁,你不应该有对病房的引用(因为它会一直被锁定,所以你不能写它) ,但您可以根据需要阅读任意数量的内容。

标签: rust rwlock


【解决方案1】:

编写您自己的结构,该结构包含Arc&lt;RwLock&lt;Foo&gt;&gt;

#[derive(Clone, Debug)]
pub struct FooReadOnly(Arc<RwLock<Foo>>);

impl FooReadOnly {
    pub fn read(&self) -> LockResult<RwLockReadGuard<'_, Foo>> {
        self.0.read()
    }

}

(完全充实的版本还将包含try_read() 的包装器。)

这里值得注意的一般模式是:您的公共类型包含Arc&lt;RwLock&lt;...&gt;&gt;,而不是Arc&lt;RwLock&lt;...&gt;&gt; 中的可见。与暴露 Arc 相比,这为您可以提供的“句柄”类型提供了更大的灵活性。这是 Rust 中相当常见的模式——如果你曾经使用过一种库类型,说明你可以克隆它并获得另一个句柄来处理同一件事,那么它很有可能在里面做同样的事情(如果它实际上不是句柄到文件描述符之类的操作系统资源)。

如果您想完全隐藏实现细节,您还可以包装 RwLockReadGuard — 它需要做的就是实现 Deref&lt;Target = Foo&gt; 并将其转发给警卫。这样的包装器还可以对Foo 的某些部分执行Derefing 之类的操作,而不是精确地&amp;Foo

【讨论】:

    猜你喜欢
    • 2023-02-20
    • 1970-01-01
    • 1970-01-01
    • 2017-05-29
    • 1970-01-01
    • 1970-01-01
    • 2018-06-10
    • 2020-05-09
    • 2021-10-18
    相关资源
    最近更新 更多