1 个不稳定版本

0.1.0 2020 年 11 月 9 日

#693 in 并发

Apache-2.0 OR MIT OR Zlib

23KB
213 代码行

lazy_id

Build Status codecov Docs Latest Version

提供 lazy_id::Id,这是一个线程安全的 64 位 ID,仅在您使用它时才将其初始化到特定值,而不是在创建时。它与 no_std (也不需要 liballoc) 一起工作,完全无锁,目前支持 1.34.0 以上的版本,并且除了 libcore 之外没有其他依赖项。

用法

use lazy_id::Id;
struct Thing {
    id: Id,
    // other fields, ...
}
// Now this function can be const, allowing use in statics
const fn new_thing() -> Thing {
    Thing { id: Id::lazy(), /* ... */ }
}
static C: Thing = new_thing();
// also works for non-static without meaningful overhead
let a = new_thing();
let b = new_thing();
// `Id` implements `PartialEq`, and many other useful traits.
assert!(a.id != b.id && a.id != C.id);

这有什么好处吗?

如果您需要为您的类型提供一个唯一的实例 Id,通常的方法是在每次分配 ID 时递增全局原子。

这里唯一的问题是,如果您想将您的类型存储在某种类型的 static 中,您需要使用 OnceCelllazy_static 或其他懒加载初始化 crate。这些 crate 没问题,并且不太可能引起性能问题的大部分时间,但如果没有这些,它们可能会令人沮丧,并且强迫用户使用您的库可能会非常不理想。

如果您之前是 no_std — 您本质上需要在执行泛型线程安全懒初始化时持有锁,而在无 std 中这样做需要自旋锁,这并不理想(这也是为什么 once_cell 需要 std 才能提供 sync 功能的原因)。

那么,为什么 lazy_id 没有这个问题呢?好吧,我们不做任何类型的泛型初始化。我们的初始化非常具体和具体,并且旨在避免锁定。这意味着我们可以轻松地避免无 std 中的任何自旋,而无需任何自旋。

无运行时依赖