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,
我的理论是在RwLock
的Community
周围有一个Arc
,然后我可以有多个写入者到RwLock
,这些写入者可以独立/同时修改friends
和index
字段CommunityContents
来自 Rc<RefCell
。
这甚至可能吗? RwLock
会不会一次只允许一个以上的作者,在这种情况下,我应该删除 RefCells
并简化整个结构?
【问题讨论】:
我建议您阅读我的那个问题的答案以了解全貌:***.com/a/45674912/4498831 我认为这是一个副本(上面链接的 Q),但经过反思我不太确定。我认为这个问题实际上太宽泛了,无法回答——你能详细说明“通过Rc<RefCell>
同时修改[...]”是什么意思吗?还是@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>> 机制