1个不稳定版本
新版本 0.1.0 | 2024年8月8日 |
---|
#538 in Rust模式
102 每月下载量
54KB
1K SLoC
token-ref-cell
此库提供了TokenRefCell
,这是一种使用外部Token
引用来同步其访问的内部可变单元格。
与像RefCell
这样的其他标准单元格不同,只要其令牌是Send + Sync
,则TokenRefCell
就是Sync
;因此,它可以在多线程程序中使用。
提供了多种令牌实现,其中最简单的是基于智能指针的:实际上,每个Box<T>
都可以用作令牌(只要T
不是一个ZST)。推荐的令牌实现是BoxToken
,它是TokenRefCell
泛型参数的默认值。
运行时成本非常轻量:使用BoxToken
时,只需进行一次指针比较即可进行TokenRefCell::borrow
/TokenRefCell::borrow_mut
(使用singleton_token!
时为零成本)。
由于一个令牌可以与多个单元格一起使用,因此可以使用单个包装着令牌的rwlock来同步多个Arc
数据的可变访问。
示例
use std::sync::{Arc, RwLock};
use token_ref_cell::{TokenRefCell, BoxToken};
let mut token = RwLock::new(BoxToken::new());
// Initialize a vector of arcs
let token_ref = token.read().unwrap();
let arc_vec = vec![Arc::new(TokenRefCell::new(0, &*token_ref)); 42];
drop(token_ref);
// Use only one rwlock to write to all the arcs
let mut token_mut = token.write().unwrap();
for cell in &arc_vec {
*cell.borrow_mut(&mut *token_mut) += 1;
}
drop(token_mut)
为什么还需要另一个crate?
基于相同原则的crate有很多:qcell
、ghost-cell
、token-cell
、singleton-cell
等。
当我开始编写 token-ref-cell
时,我只知道 token-cell
,因为它是由我之前同公司的一个人编写的。但我想采取新的方法,特别是设计一个比标准 RefCell
更接近的 API,因此得名 TokenRefCell
。实际上,我的目标很简单:使图例编译,为此我需要启用“重新借用”,即重新使用在可变借用中使用的令牌,以可变借用一个“子单元格”。
当我对我得到的结果满意,在发布之前,我搜索其他类似的项目,我找到了上面的列表,并意识到我已经像很多人一样重新实现了相同的概念,特别是 qcell
,它使用 Box
作为其单元格令牌/所有者。然而,这个新的实现仍然有一些特定的特性使其相关
- 一个接近
RefCell
的熟悉 API; - 一个具有单个
Token
特性的统一 API,与qcell
提供的四种不同单元格类型相反; - 由于
Token
特性的简单性,有更多选择令牌实现:单例类型、智能指针、固定/非固定引用等; no_std
实现,与自定义分配器兼容(不要求alloc
包,并且使用RefToken
等示例时不要求任何分配器);- 重新借用。