16 个版本 (4 个重大更改)

0.5.4 2022 年 5 月 26 日
0.5.3 2022 年 3 月 23 日
0.4.2 2021 年 11 月 28 日
0.3.3 2021 年 11 月 6 日
0.1.0 2021 年 10 月 31 日

#392并发

每月 39 次下载

MIT 许可证

9KB
159

with_lock

死锁自由

使用 with_lock?在讨论中分享它!

文档

这个crate提供了一个简单的管理Mutex的方法,并让你的代码摆脱死锁。它由parking_lot提供。

示例

假设你有这段代码

use std::sync::Mutex;

fn main() {
    let a = Mutex::new(2);
    let b = Mutex::new(3);
    let a_lock = a.lock().unwrap();
    let b_lock = b.lock().unwrap();
    assert_eq!(*a_lock + *b_lock, 5);
    let a_lock_2 = a.lock().unwrap();
    let b_lock_2 = b.lock().unwrap();
    assert_eq!(*a_lock_2 + *b_lock_2, 5);
}

这段代码将顺利运行第一个 assert_eq!,但第二个会因为死锁而不会断言。

然而,我们可以通过将我们的手动调用 .lock 替换为 .with_lock 来防止这种情况。不会出错的代码看起来可能像这样

use with_lock::WithLock;

fn main() {
    let a = WithLock::<i64>::new(2);
    let b = WithLock::<i64>::new(3);
    let a_lock = a.with_lock(|s| *s);
    let b_lock = b.with_lock(|s| *s);
    assert_eq!(a_lock + b_lock, 5);
    let a_lock_2 = a.with_lock(|s| *s);
    let b_lock_2 = b.with_lock(|s| *s);
    assert_eq!(a_lock_2 + b_lock_2, 5);
}

这个测试会通过,并且两个断言都会得到满足。这是一个防止死锁的例子。

类似 Cell 的 API

with_lock 提供了一个由 Mutex 提供的类似 .Cell 的自定义 API。

use with_lock::MutexCell;

fn main() {
    let a = MutexCell::new(2);
    let b = MutexCell::new(3);
    let a_locked = a.get();
    let b_locked = b.get();
    assert_eq!(a_locked + b_locked, 5);
    let a_lock_2 = a.get();
    let b_lock_2 = b.get();
    assert_eq!(a_lock_2 + b_lock_2, 5);
}

更多示例,请参阅示例目录。可以通过克隆此存储库并运行 cargo run --example <example_name> 来运行这些示例。

依赖关系

~0.4–5.5MB
~11K SLoC