5 个版本
使用旧的 Rust 2015
0.2.1 | 2023年9月13日 |
---|---|
0.2.0 | 2018年6月14日 |
0.2.0-rc.1 | 2018年4月28日 |
0.1.1 | 2018年4月7日 |
0.1.0 | 2018年4月6日 |
#206 in 并发
26KB
318 行
incr
简单的、快速且自包含的结构体,用于跟踪新观察到的值(u64
)是否大于之前观察到的最大值。
使用案例包括消息序列号、时间戳以及其他需要快速评估传入数据是否“新”的情况,即其编号是否大于任何之前的值。
所有结构体都包含一个 is_new
函数,如果传入的值是新最大值,则返回 true
,同时将新值存储以供未来值检查。
其中两个 is_new
实现的函数(Incr
和 Map
)需要一个 &mut self
签名,而 RcIncr
和 AtomicIncr
由于 RcIncr
的内部可变性以及 AtomicIncr
的线程安全同步,只需要 &self
。
检查新值的开销极小:单线程实现的 0-2ns,以及 AtomicIncr
的 ~5-10ns,除非在病态竞争的情况下。在最坏情况下,对 AtomicIncr
的噩梦场景基准测试中,可能会引起数百纳秒的延迟。在更现实的 24 个线程竞争递增原子但每次迭代都释放的情况下,检查在 ~5-10ns 范围内。
启用“nightly”功能(默认开启)允许将 AtomicU64
作为 AtomicIncr
的后端存储(与 AtomicUsize
相反)。另外,需要 nightly 才能运行基准测试。
用法
将以下内容添加到您的 Cargo.toml
[dependencies]
incr = "0.2"
示例
简单用法
use incr::Incr;
let mut last = Incr::default();
assert_eq!(last.is_new(1), true);
assert_eq!(last.is_new(1), false);
assert_eq!(last.is_new(2), true);
assert_eq!(last.get(), 2);
AtomicIncr
提供一个线程安全的实现
extern crate incr;
use std::thread::{spawn, JoinHandle};
use std::sync::{Arc, Barrier};
use incr::AtomicIncr;
fn main() {
let last: AtomicIncr = Default::default();
let barrier = Arc::new(Barrier::new(2));
let thread: JoinHandle<u64> = {
let barrier = Arc::clone(&barrier);
let last = last.clone();
spawn(move || {
assert_eq!(last.is_new(2), true);
assert_eq!(last.is_new(3), true);
assert_eq!(last.is_new(3), false);
barrier.wait();
last.get()
})
};
barrier.wait();
assert_eq!(last.is_new(3), false);
assert_eq!(thread.join().unwrap(), 3);
}