Тип Ordering
Тип Ordering используется в атомарных операциях
для указания порядка доступа к памяти. Атомики находятся
в модуле std::sync::atomic, а сам тип
Ordering импортируется оттуда же. Он представляет
собой перечисление с пятью вариантами: Relaxed,
Release, Acquire, AcqRel и
SeqCst. Параметром атомарные методы принимают
значение типа Ordering, которое определяет,
какие гарантии синхронизации нужны при чтении или записи.
Вариант Relaxed даёт минимум гарантий: операции
не создают отношения «до/после» с другими потоками.
Вариант Release применяется при записи и гарантирует,
что все предыдущие записи станут видны потоку, который
выполнит чтение с Acquire. Вариант Acquire
применяется при чтении и гарантирует, что все последующие
чтения увидят данные, опубликованные через Release.
Вариант AcqRel объединяет оба порядка и используется
в операциях чтения-изменения-записи. Вариант SeqCst
задаёт самый строгий последовательно согласованный порядок,
единый для всех потоков.
Синтаксис
use std::sync::atomic::Ordering;
Ordering::Relaxed
Ordering::Release
Ordering::Acquire
Ordering::AcqRel
Ordering::SeqCst
Пример
Давайте выполним атомарную загрузку и сохранение
с порядком SeqCst:
use std::sync::atomic::{AtomicUsize, Ordering};
fn main()
{
let value = AtomicUsize::new(0);
value.store(5, Ordering::SeqCst);
let res = value.load(Ordering::SeqCst);
println!("{}", res);
}
Результат выполнения кода:
5
Пример
Давайте сравним порядок Relaxed и порядок
SeqCst при атомарном сложении:
use std::sync::atomic::{AtomicUsize, Ordering};
fn main()
{
let value = AtomicUsize::new(0);
let res1 = value.fetch_add(1, Ordering::Relaxed);
let res2 = value.fetch_add(1, Ordering::SeqCst);
println!("{}", res1);
println!("{}", res2);
println!("{}", value.load(Ordering::SeqCst));
}
Результат выполнения кода:
0
1
2
Пример
Давайте выполним атомарное сравнение с обменом
с порядком AcqRel:
use std::sync::atomic::{AtomicUsize, Ordering};
fn main()
{
let value = AtomicUsize::new(1);
let res = value.compare_exchange(
1,
10,
Ordering::AcqRel,
Ordering::Acquire,
);
println!("{:?}", res);
println!("{}", value.load(Ordering::SeqCst));
}
Результат выполнения кода:
Ok(1)
10
Смотрите также
-
тип
atomic.Ordering,
который задаёт порядок доступа к памяти в атомарных операциях -
метод
load,
который атомарно читает значение с указанным порядком -
метод
store,
который атомарно записывает значение с указанным порядком -
метод
compare_exchange,
который атомарно сравнивает и заменяет значение