En la documentación de std::memory_order
cppreference.com hay un ejemplo de pedido relajado:
Pedidos relajados
Las operaciones atómicas etiquetadas
memory_order_relaxed
no son operaciones de sincronización; no imponen un orden entre los accesos concurrentes de memoria. Solo garantizan la atomicidad y la coherencia del orden de modificación.Por ejemplo, con x e y inicialmente cero,
// 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
se permite producir r1 == r2 == 42 porque, aunque A se secuencia antes de B dentro del hilo 1 y C se secuencia antes de D dentro del hilo 2, nada impide que D aparezca antes de A en el orden de modificación de y, y B de apareciendo antes de C en el orden de modificación de x. El efecto secundario de D en y podría ser visible para la carga A en el subproceso 1, mientras que el efecto secundario de B en x podría ser visible para la carga C en el subproceso 2. En particular, esto puede ocurrir si D se completa antes de C en subproceso 2, ya sea debido a la reordenación del compilador o en tiempo de ejecución.
dice "C está secuenciado antes que D dentro del hilo 2".
De acuerdo con la definición de secuenciado antes, que se puede encontrar en el Orden de evaluación , si A se secuencia antes que B, la evaluación de A se completará antes de que comience la evaluación de B. Dado que C se secuencia antes de D dentro del hilo 2, C debe completarse antes de que D comience, por lo tanto, la parte de condición de la última oración de la instantánea nunca se cumplirá.