link
OnceLock
A synchronization primitive which can nominally be written to only once.
This type is a thread-safe OnceCell, and can be used in statics. In many simple cases, you can use LazyLock<T, F> instead to get the benefits of this type with less effort: LazyLock<T, F> “looks like” &T because it initializes with F on deref! Where OnceLock shines is when LazyLock is too simple to support a given case, as LazyLock doesn’t allow additional inputs to its function after you call LazyLock::new(|| ...).
A OnceLock can be thought of as a safe abstraction over uninitialized data that becomes initialized once written.
Unlike Mutex, OnceLock is never poisoned on panic.
- 명목상 한 번만 쓸 수 있는 동기화 프리미티브.
이 유형은 스레드에 안전한 원스셀(OnceCell)로, 통계학에서 사용할 수 있습니다. 많은 간단한 경우에 LazyLock<T, F>를 사용하여 적은 노력으로 이 유형의 이점을 얻을 수 있습니다: LazyLock<T, F>는 디레프에서 F로 초기화되기 때문에 &T처럼 보입니다! 원스락이 빛나는 이유는 LazyLock이 너무 단순해서 특정 케이스를 지원할 수 없을 때입니다. LazyLock을 호출한 후 LazyLock이 기능에 추가 입력을 허용하지 않기 때문입니다
원스락은 일단 작성되면 초기화되는 초기화되지 않은 데이터를 안전하게 추상화한 것으로 생각할 수 있습니다.
뮤텍스와 달리 원스락은 패닉에 중독되지 않습니다.
use std::sync::OnceLock;
static CELL: OnceLock<usize> = OnceLock::new();
fn main() {
// `OnceLock` has not been written to yet.
assert!(CELL.get().is_none());
// Spawn a thread and write to `OnceLock`.
std::thread::spawn(|| {
let value = CELL.get_or_init(|| 12345);
assert_eq!(value, &12345);
})
.join()
.unwrap();
// `OnceLock` now contains the value.
assert_eq!(CELL.get(), Some(&12345),);
}
``
# `OnceLock` part2
```rs
use std::sync::OnceLock;
static WINNER: OnceLock<&str> = OnceLock::new();
fn main() {
let winner = std::thread::scope(|s| {
s.spawn(|| WINNER.set("thread"));
std::thread::yield_now(); // give them a chance...
WINNER.get_or_init(|| "main")
});
println!("{winner} wins!");
}
```