1 个不稳定发布

0.1.0 2024年1月6日

#928 in 数据结构

MIT 许可证

20KB
457

提供读-复制-更新锁原语

RCU 锁是 Linux 内核中流行的并发原语。它们支持多个并发读者访问单个写者更新的值。RCU 锁对于将新的配置值发布到多个读者或作为轻量级垃圾回收机制非常有用。

示例

要创建一个新的 RCU 锁,请使用初始值调用 Rcu::new。然后通过调用 Rcu::reader 创建一个新的 Reader,这提供了一个句柄,可以通过调用 Reader::read 来访问值。

# use read_copy_update::Rcu;
# use std::{thread, time::Duration};
let mut rcu = Rcu::new(10);

// This thread can read the value, new updates will be published without requiring locks.
let mut rdr = rcu.reader();
thread::spawn(move || {
    println!("{}", *rdr.read()); // prints '10'
    thread::sleep(Duration::from_millis(1));
    println!("{}", *rdr.read()); // prints '20'
});

// The value can be updated on the main thread, independently of other readers.
rcu.write(20);

一个常见的用例是在线程局部存储中共享读者。启用 thread-local 特性标志后,Reader 实例可以与线程相关联,允许在线程局部存储中进行无锁读取和发布。

# use read_copy_update::{Rcu, ThreadLocal};
# use std::{thread, time::Duration};
let mut rcu = Rcu::new(10);
let tls = ThreadLocal::new(&rcu);

thread::scope(|s| {
    s.spawn(|| {
        let val = tls.get_or_init();
        println!("{}", *val);
    });
    s.spawn(|| {
        let val = tls.get_or_init();
        println!("{}", *val);
    });
});

// The value can be updated on the main thread, independently of other readers.
rcu.write(20);

设计

内部,新值在堆上分配并关联到一个纪元。读者在 read() 调用中拉入指针并增加每个读者的纪元计数器。回收基于确保所有活动读者已将他们的纪元推进到要回收的值。由于这种设计,嵌套的 read() 调用不会获取最新的值,只有在所有引用都已释放后,值才会被刷新。

依赖项

~0–26MB
~333K SLoC