Nella documentazione di std::memory_order
su cppreference.com c'è un esempio di ordinamento semplificato :
Ordinazione rilassata
Le operazioni atomiche contrassegnate
memory_order_relaxed
non sono operazioni di sincronizzazione; non impongono un ordine tra gli accessi simultanei alla memoria. Garantiscono solo atomicità e coerenza dell'ordine di modifica.Ad esempio, con xey inizialmente zero,
// Thread 1: r1 = y.load(std::memory_order_relaxed); // A x.store(r1, std::memory_order_relaxed); // B // Thread 2: r2 = x.load(std::memory_order_relaxed); // C y.store(42, std::memory_order_relaxed); // D
è consentito produrre r1 == r2 == 42 perché, sebbene A sia in sequenza prima di B all'interno del thread 1 e C sia in sequenza prima di D all'interno del thread 2, nulla impedisce a D di apparire prima di A nell'ordine di modifica di y, e B da appare prima di C nell'ordine di modifica di x. L'effetto collaterale di D su y potrebbe essere visibile al carico A nella filettatura 1 mentre l'effetto collaterale di B su x potrebbe essere visibile al carico C nella filettatura 2. In particolare, ciò può verificarsi se D è completato prima che C in thread 2, dovuto al riordino del compilatore o in fase di esecuzione.
dice "C è sequenziato prima di D all'interno del thread 2".
Secondo la definizione di sequenziato prima, che si trova nell'ordine di valutazione , se A è sequenziato prima di B, la valutazione di A sarà completata prima che inizi la valutazione di B. Poiché C è sequenziato prima di D all'interno del thread 2, C deve essere completato prima dell'inizio di D, quindi la parte della condizione dell'ultima frase dell'istantanea non sarà mai soddisfatta.