Initialize Global Config Once with OnceLock
Initialize process-wide configuration exactly once across threads with std::sync::OnceLock, then read it without locks or clones.
Code
use std::sync::{Arc, Barrier, OnceLock};
use std::thread;
#[derive(Debug, Clone)]
struct Config {
service: String,
workers: usize,
debug: bool,
}
impl Default for Config {
fn default() -> Self {
Self {
service: "orders".to_string(),
workers: 4,
debug: false,
}
}
}
static CONFIG: OnceLock<Config> = OnceLock::new();
fn config() -> &'static Config {
CONFIG.get_or_init(|| {
println!("loading configuration once");
Config::default()
})
}
fn main() {
let barrier = Arc::new(Barrier::new(4));
let mut handles = Vec::new();
for worker in 0..4 {
let barrier = Arc::clone(&barrier);
handles.push(thread::spawn(move || {
barrier.wait();
let current = config();
println!(
"worker {worker}: {} ({} workers)",
current.service, current.workers
);
current.workers
}));
}
let total: usize = handles
.into_iter()
.map(|handle| handle.join().expect("worker panicked"))
.sum();
println!("total workers: {total}");
println!("same instance: {}", std::ptr::eq(config(), config()));
}
Report a problem with this exampleOpens a pre-filled issue on GitHub.