1 个不稳定版本
0.1.0 | 2024年5月22日 |
---|
#19 in #deadlock
在deadlocker中使用
23KB
468 行
Deadlocker
Deadlocker是一个旨在以构建者模式灵感消除死锁的crate
该crate的主要功能是derive宏,它将执行以下操作
- 为每种可能持有的锁的组合创建一个结构体
- 为在原始结构体中持有锁的引用创建一个结构体
- 允许锁器结构体按任意顺序链式调用方法来指定所需的锁
- 在锁器结构体上实现一个最终锁定方法,它将以确定性的顺序锁定所需的锁,消除由于锁获取顺序不当而导致的死锁
示例
use deadlocker::Locker;
use std::sync::{Arc, Mutex};
type Foo = Vec<usize>;
type Bar = usize;
type Baz = u8;
#[derive(Locker)]
pub struct MyStruct {
#[result]
pub foo: Arc<Mutex<Foo>>,
#[result]
pub bar: Arc<Mutex<Bar>>,
#[result]
pub baz: Arc<Mutex<Baz>>,
}
pub fn main() {
let mut my_struct = MyStruct {
foo: Arc::new(Mutex::new(Vec::new())),
bar: Arc::new(Mutex::new(0)),
baz: Arc::new(Mutex::new(0)),
};
{
let mut lock = my_struct
.locker()
.baz()
.foo()
.lock()
.expect("Mutex was poisoned");
lock.foo.push(1);
**lock.baz = 1;
}
{
let lock = my_struct
.locker()
.bar()
.foo()
.baz()
.lock()
.expect("Mutex was poisoned");
println!("Foo: {:?}", **lock.foo);
println!("Bar: {:?}", **lock.bar);
println!("Baz: {:?}", **lock.baz);
}
}
属性
每个字段都可以用多个属性来注释,以修改derive宏的行为。效果如下,示例在示例目录中提供
outer_type
指示外部类型,即锁定部分,与inner_type相对,即内部类型。这是inner_type的补充,通常只指定其中一个,inner_type具有优先权。
它使用正则表达式指定,其中只有一个捕获组,该捕获组是inner_type应该出现的位置。指定外部类型在内部类型长且复杂时非常有用。
#[outer_type = "Arc<Mutex<(.*)>>"]
请注意,这默认设置为上述值,这意味着如果您的字段符合该模式,则不需要指定任何内容。有关更多信息,请参阅基本示例。
inner_type
指示内部类型,即被锁保护的类型。这是outer_type的补充,通常只指定其中一个,此属性具有优先权。
#[inner_type = "usize"]
async_lock
将锁标记为异步,这将导致包含标记为 async_lock
字段的链中的最终 lock
方法也变为异步。这不会影响结构体中的其他锁,因此最终 lock
方法不需要异步,仅仅因为一些锁是异步的。
#[async_lock]
lock_method
指示如何从锁获取 inner_type。对于 std::sync::Mutex
,这是 lock()
,而对于 tokio::sync::Mutex
,它是 lock().await
。注意省略了开头的点以及结尾的分号。
#[lock_method = "lock()"]
对于同步锁,这默认为 lock()
,而对于异步锁是 lock().await
,这意味着大多数人不需要指定此参数。
result
将锁标记为在其守护者上产生结果,而不是直接产生守护者。这适用于 std::sync::Mutex
,但不适用于 tokio::sync::Mutex
。这导致包含标记为 result
的字段的链中的最终 lock
方法返回一个结果,正常返回的结构体嵌入在其 Ok
变体中。
#[result]
include
指示此字段应包含在锁结构体中。存在单个标记为此类的字段意味着没有标记的字段应被包含。如果有一个大型状态结构体,其中只有一小部分是锁,则非常有用。这覆盖了任何 exclude 属性。
#[include]
exclude
指示此字段不应包含在锁结构体中。如果有一个大型状态结构体,其中大多数字段都是锁,则非常有用。
#[exclude]
依赖关系
~2.8–4.5MB
~79K SLoC