#future #tokio #mutex #async

nightly tokio-lk

基于 ID 的锁原语,具有 futures 感知功能

5 个版本

0.2.2 2020 年 3 月 26 日
0.2.1 2020 年 3 月 26 日
0.1.3 2020 年 3 月 17 日

#834异步

每月 24 次下载

MIT 许可证

29KB
674

Crates.io License Build Status

tokio-lk 版本 - 0.2.2

Tokio-lk

** 用于 tokio 的 ID 锁 future **

Lock future 在获取互斥锁后会返回 Guard,以便在后续 future 中保持锁。要将 Guard 移动到 future 输出中。要释放互斥锁,只需从您的 future 链中丢弃 Guard

每个 Lock 对象都会分配一个 唯一的 ID。直到 ID 生成达到 USIZE_MAX,唯一性是有保证的。在生成新的 Lock 之前,请确保丢弃旧的 Lock。

变更日志

  • 0.2.2 - 在 cargo.toml 中进行小修,以便让 docs.rs 生成所有功能的文档
  • 0.2.1 - 添加了使用 hashbrown 或 dashmap 的功能。为 hashmap 抽象添加了 KeyPool
  • 0.2.0 - 升级到 futures 0.3 和 tokio 0.2
  • 0.1.3 - 现在依赖于 dashmap 以替换 RwLock<HashMap>
  • 0.1.2 - 第一个稳定版本

示例

use std::time::{Duration, Instant};
use tokio_lk::*;
use futures::prelude::*;
use tokio::runtime::Runtime;
use tokio::time::delay_for;

let mut rt = Runtime::new().unwrap();
let map = KeyPool::<MapType>::new();
let now = Instant::now();
// this task will compete with task2 for lock at id 1
let task1 = async {
    let _guard = Lock::fnew(1, map.clone()).await.await;
    delay_for(Duration::from_millis(100)).await;
};
// this task will compete with task1 for lock at id 1
let task2 = async {
    let _guard = Lock::fnew(1, map.clone()).await.await;
    delay_for(Duration::from_millis(100)).await;
};
// no other task compete for lock at id 2
let task3 = async {
    let _guard = Lock::fnew(2, map.clone()).await.await;
    delay_for(Duration::from_millis(100)).await;
};
rt.block_on(async { tokio::join!(task1, task2, task3) });

功能

  • hashbrown
    • 提供 MapType 作为 hashbrown::HashMap 的类型别名,用于 KeyPool 初始化
  • dashmap
    • 提供 DashMapType 作为 dashmap::DashMap 的类型别名,用于 KeyPool 初始化
  • 默认:hashbrown
  • all:both hashbrown and dashmap

基准测试

要运行基准测试,请在提示符中执行以下命令

cargo bench -- --nocapture

lock1000_parallel 基准测试是运行 1000 个由单个锁锁定的 futures 来更新计数器。 lock1000_serial 基准测试是在单个线程中运行类似操作。目前我们的实现比单线程版本慢约 4~5 倍。

许可证

许可下

贡献

除非您明确声明,否则您提交给作品包含的任何贡献都将根据上述条款许可,不附加任何额外的条款或条件。

依赖关系

~7.5MB
~125K SLoC