4 个版本
0.2.2 | 2020年2月5日 |
---|---|
0.2.1 | 2020年2月3日 |
0.2.0 | 2020年1月28日 |
0.1.0 | 2020年1月26日 |
#409 在 并发 中
25KB
484 行
TLID
通过为每个线程分配一个范围来实现低级别的唯一 ID 生成。
优点
- 唯一数字,简单递增
- 无锁,无原子操作
::next()
- 所有依赖都是可选的
- 速度:600,000,000/s
- 示例代码
- 严格的 CI 测试
缺点
- 范围需要在之前知道,例如 u64,对于 1024 个线程来说,每个线程只能有
2^54
个可用的 ID - 不是密码学安全的(简单递增)
- 池的创建和删除需要同步
- beta:在
0.9
之前的 tlid 不适合生产环境,可能存在错误或非最佳 ID 返回行为
有很多 ID Crates,但几乎所有都使用一些随机值、时间或原子行为来在多个线程中保持唯一性。Tlid (线程本地唯一 ID) 通过为每个线程分配一个初始范围来旨在实现唯一性。这需要为每个池(和子池)设置一个范围,这使得 ::next()
非常快。
::next()
有 3 种行为选项,不能混合使用
- 已检查:以每次操作进行范围检查为代价保证唯一 ID
- 包装:具有相同的检查,但在所有 ID 都使用完毕后,不会使 Pool 无用,而是循环使用。ID 不再唯一,但对于短缓冲区(如网络)很有用
- 未检查:最快的无保证方法,在
::next()
方法中不检查边界。
依赖关系
[dependencies]
tlid = "0.2"
示例
// 请参阅 示例 文件夹
use tlid::{Pool, Checked};
use std::{
thread,
time::Duration,
result::Result,
error::Error,
};
fn worker(thread: u8, p: &mut Pool<Checked<u64>>) {
//work
for _ in 0..2 {
thread::sleep(Duration::from_millis(1));
println!("[{}] did work: {}", thread, p.next().unwrap());
}
}
fn main() -> Result<(), Box<dyn Error>> {
let mut p = Pool::new_full();
for i in 0..5 {
let mut local_pool = p.subpool(5)?;
thread::spawn(move ||
worker(i, &mut local_pool)
);
}
thread::sleep(Duration::from_millis(100));
Ok(())
}
示例输出(如您所见,所有 ID 都是唯一的)
[0] did work: 0
[1] did work: 2
[2] did work: 4
[0] did work: 1
[1] did work: 3
[3] did work: 6
[4] did work: 8
[2] did work: 5
[3] did work: 7
[4] did work: 9
许可证
许可方式为以下之一
- Apache许可证第2版,(LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
由您选择。
贡献
除非您明确说明,否则您按照Apache-2.0许可证定义提交的旨在包含在作品中的任何贡献,应按上述方式双许可,不附加任何额外条款或条件。
依赖关系
~95–320KB