Arc 是不是允许 RwLock 拥有多个写入器?

Posted

技术标签:

【中文标题】Arc 是不是允许 RwLock 拥有多个写入器?【英文标题】:Does an Arc allow an RwLock to have more than one writer?Arc 是否允许 RwLock 拥有多个写入器? 【发布时间】:2019-08-05 18:36:14 【问题描述】:

我正在玩这个玩具结构:

pub struct Community 
    pub community_contents: RwLock<CommunityContents>,


pub struct CommunityContents 
    pub friends: RefCell<HashMap<FriendID, FriendData>>, 
    pub index: RefCell<HashMap<u64, BTreeMap<FriendID, FriendData>>>, 
    pub authenticated: bool,
    pub age: u64,     
    pub height: u64,

我的理论是在RwLockCommunity 周围有一个Arc,然后我可以有多个写入者到RwLock,这些写入者可以独立/同时修改friendsindex 字段CommunityContents 来自 Rc&lt;RefCell

这甚至可能吗? RwLock 会不会一次只允许一个以上的作者,在这种情况下,我应该删除 RefCells 并简化整个结构?

【问题讨论】:

我建议您阅读我的那个问题的答案以了解全貌:***.com/a/45674912/4498831 我认为这是一个副本(上面链接的 Q),但经过反思我不太确定。我认为这个问题实际上太宽泛了,无法回答——你能详细说明“通过Rc&lt;RefCell&gt;同时修改[...]”是什么意思吗?还是@FrenchBoiethios 链接的问题也回答了您的问题? @trentcl 我的意思是让线程同时修改朋友和索引字段。一组线程修改好友同时索引好友被另一个线程修改。 @Gmanman 好吧,你只需要细化你的锁。不要将整个社区放在一个 RwLock 中,而是将好友和索引放在单独的 RwLock 中 【参考方案1】:

没有。

Arc 不允许对其持有的类型进行突变。只能共享不可变引用,Arc 也不例外。

来自Arc docs:

默认情况下,Rust 中的共享引用不允许突变,Arc 也不例外:您通常无法获得对 Arc 中某些内容的可变引用。如果您需要通过 Arc 进行变异,请使用 Mutex、RwLock 或其中一种 Atomic 类型。

这意味着您必须存储具有内部可变性的类型...RwLock 是其中一种类型,并且无论它是否包含在 Arc 中,它的行为都是相同的。

来自RwLock 文档:

这种类型的锁在任何时间点允许多个读取器或最多一个写入器。

无论你做什么,使用安全 Rust 都不可能在两个不同的地方获得可变引用,唯一的方法是使用 unsafe ,这无论如何都会导致未定义的行为,像 RwLock 这样的类型确实使用 unsafe ,但是,他们保证写(可变访问)是独占的,事实上,如果有人在写它就无法读取,如果有人在读它就无法写入,这就是这句话的意思。

【讨论】:

以上是关于Arc 是不是允许 RwLock 拥有多个写入器?的主要内容,如果未能解决你的问题,请参考以下文章

了解 Rust 中的线程安全 RwLock<Arc<T>> 机制

线程同步之读写锁

C# ReaderWriterLockSlim类

pthread读写锁不起作用吗? [关闭]

为什么rwlock比linux内核中的seqlock更受欢迎? [关闭]

OpenGL着色器 - 重叠多个纹理