5 个版本
0.1.4 | 2024年2月15日 |
---|---|
0.1.3 | 2021年11月22日 |
0.1.2 | 2021年11月21日 |
0.1.1 | 2021年11月17日 |
0.1.0 | 2021年11月15日 |
#197 in 并发
12KB
134 行
atomic-interval
实现了一个非常小的库,用于实现一个 无锁 原子定时器。
文档
示例
在下面的示例中,我们有一个并发场景,其中多个线程想要将数据样本推向单个公共实体(例如,一个静态函数、一个多引用对象等)。
该实体想要提供一个“限制器”机制,实际上它以有限的频率处理一个样本。
因此,即使并发线程以更高的频率推送,每个周期也只处理一个样本(来自一个线程)。
AtomicInterval
可以在不添加额外同步机制的情况下使用,因为它已经可以在线程之间安全地共享。
use atomic_interval::AtomicIntervalLight;
use once_cell::sync::OnceCell;
use std::thread;
use std::time::Duration;
const MAX_PERIOD_SAMPLING: Duration = Duration::from_secs(1);
fn push_sample(id_thread: usize, value: u8) {
// Note AtomicInterval can be used without additional
// sync wrapper (e.g., a `Mutex`) as it is atomic.
static LIMITER: OnceCell<AtomicIntervalLight> = OnceCell::new();
let limiter_init = || AtomicIntervalLight::new(MAX_PERIOD_SAMPLING);
// Only one threads can push a sample for each PERIOD.
// We limit the samples acquisition with a interval.
if LIMITER.get_or_init(limiter_init).is_ticked() {
println!("Thread '{}' pushed sample: '{}'", id_thread, value);
}
}
fn main() {
let num_threads = num_cpus::get();
(0..num_threads)
.map(|id_thread| {
thread::spawn(move || loop {
let sample = rand::random();
// Multiple threads concurrently try to push a sample.
push_sample(id_thread, sample);
thread::sleep(Duration::from_millis(1));
})
})
.collect::<Vec<_>>()
.into_iter()
.for_each(|join_handle| join_handle.join().unwrap());
}
依赖项
~0.8–2.4MB
~42K SLoC