#atomic #interval #timer #lock-free #time

atomic-interval

原子定时器的微小实现

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 并发

MIT/Apache

12KB
134

atomic-interval

crates.io docs.rs Build

实现了一个非常小的库,用于实现一个 无锁 原子定时器。

文档

Docs.rs

示例

在下面的示例中,我们有一个并发场景,其中多个线程想要将数据样本推向单个公共实体(例如,一个静态函数、一个多引用对象等)。

该实体想要提供一个“限制器”机制,实际上它以有限的频率处理一个样本。

因此,即使并发线程以更高的频率推送,每个周期也只处理一个样本(来自一个线程)。

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