← 中文资源

简体中文版本

用 OnceLock 初始化全局配置

用 std::sync::OnceLock 保存进程级配置,多个线程首次读取时只执行一次初始化,之后无需加锁即可获得同一个静态引用。

阅读英文原文

功能说明

示例用 std::sync::OnceLock 保存进程级配置。四个线程在 Barrier 处同步后同时调用 config(),get_or_init 保证初始化闭包只执行一次,其余线程拿到同一个 &'static Config。读取路径没有互斥锁,也不需要克隆整个结构,适合启动后不再变化的配置。

关键代码

static CONFIG: OnceLock<Config> = OnceLock::new();

fn config() -> &'static Config {
    CONFIG.get_or_init(|| {
        println!("loading configuration once");
        Config::default()
    })
}

初始化闭包在首次调用时执行;如果闭包 panic,OnceLock 会保持未初始化状态,后续调用会再次尝试。

使用注意

  • OnceLock 只允许初始化一次,之后无法替换配置;需要热更新应改用 RwLock 或 atomic 快照。
  • 读取返回 'static 引用,因此配置对象不能包含短生命周期借用。
  • 初始化闭包应避免执行可能长时间阻塞的 I/O,否则其他线程会一起等待。
  • 多线程同时首次访问时只有一个线程真正初始化,其余线程阻塞到完成。
  • 测试中无法重置静态变量,涉及不同配置的用例应把逻辑抽到可注入的函数里。

验证方式

运行示例应只打印一次 loading configuration once,四个线程都输出 orders (4 workers),总和为 16,最后 same instance: true。把 Barrier 去掉后仍只会初始化一次,但输出顺序可能变化。