În timp ce primitivele grele de sincronizare precum Mutex sau RwLock apelează la apeluri de sistem (syscalls) pentru a suspenda firele în nucleul sistemului de operare, operațiunile atomice (Atomics) din modulul std::sync::atomic operează direct la nivel de instrucțiuni de procesor (CPU hardware instructions), oferind sincronizare concurentă de ultra-înaltă viteză fără blocaje (Lock-Free).
Fiecare operațiune atomică solicită un parametru std::sync::atomic::Ordering, care specifică compilatorului și procesorului ce optimizări de reordonare a instrucțiunilor sunt permise în jurul acelei linii de cod.
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
pub struct SpinLock {
blocat: AtomicBool,
}
impl SpinLock {
pub const fn new() -> Self {
SpinLock {
blocat: AtomicBool::new(false),
}
}
pub fn lock(&self) {
// Încercăm să schimbăm atomica din false în true.
// Folosim Ordering::Acquire: nicio citire sau scriere viitoare din secțiunea critică
// nu poate fi reordonată înaintea acestei linii!
while self.blocat.swap(true, Ordering::Acquire) {
// Cedează cuanta CPU pentru a evita consumul inutil de energie:
std::hint::spin_loop();
}
}
pub fn unlock(&self) {
// Folosim Ordering::Release: toate modificările efectuate în secțiunea critică
// sunt garantate să devină vizibile altor fire înainte ca valoarea să devină false!
self.blocat.store(false, Ordering::Release);
}
}
fn main() {
let lock = Arc::new(SpinLock::new());
let lock_clone = Arc::clone(&lock);
let handle = thread::spawn(move || {
lock_clone.lock();
println!("Firul 2 a obținut blocajul atomic!");
lock_clone.unlock();
});
lock.lock();
println!("Firul 1 se află în secțiunea critică.");
lock.unlock();
handle.join().unwrap();
}
Clasificarea Nivelurilor de Ordine a Memoriei (Memory Ordering)
| Nivel de Ordonare | Garanții de Sincronizare Hardware | Cost / Penalizare de Performanță |
|---|---|---|
Relaxed |
Garantează doar atomicitatea operației pe acea variabilă. Permite reordonarea liberă a altor instrucțiuni din jur. | Minim (instrucțiune nativă fără bariere de memorie). |
Release |
Barieră de scriere: nicio operație anterioară nu poate fi reordonată după această scriere. | Scăzut spre mediu (folosit la publicarea de date). |
Acquire |
Barieră de citire: nicio operație viitoare nu poate fi reordonată înaintea acestei citiri. | Scăzut spre mediu (folosit la consumarea de date). |
SeqCst |
Sequential Consistency: garantează o ordine globală strictă observabilă identic de către toate nucleele CPU. | Maxim (inserează instrucțiuni grele de barieră de memorie hardware – MFENCE). |