Espacios de nombres
Variantes
Acciones

std::memory_order

De cppreference.com
< cpp‎ | atomic

 
 
Operaciones de biblioteca Atómica
Tipos
Original:
Types
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
atomic(C++11)
atomic_is_lock_free(C++11)
Funciones
Original:
Functions
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
atomic_store
atomic_store_explicit
(C++11)
(C++11)
atomic_load
atomic_load_explicit
(C++11)
(C++11)
atomic_exchange
atomic_exchange_explicit
(C++11)
(C++11)
atomic_compare_exchange_weak
atomic_compare_exchange_weak_explicit
atomic_compare_exchange_strong
atomic_compare_exchange_strong_explicit
(C++11)
(C++11)
(C++11)
(C++11)
atomic_fetch_add
atomic_fetch_add_explicit
(C++11)
(C++11)
atomic_fetch_sub
atomic_fetch_sub_explicit
(C++11)
(C++11)
atomic_fetch_and
atomic_fetch_and_explicit
(C++11)
(C++11)
atomic_fetch_or
atomic_fetch_or_explicit
(C++11)
(C++11)
atomic_fetch_xor
atomic_fetch_xor_explicit
(C++11)
(C++11)
Banderas atómicas
Original:
Atomic flags
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
atomic_flag(C++11)
atomic_flag_test_and_set
atomic_flag_test_and_set_explicit
(C++11)
(C++11)
atomic_flag_clear
atomic_flag_clear_explicit
(C++11)
(C++11)
Inicialización
Original:
Initialization
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
atomic_init(C++11)
ATOMIC_VAR_INIT(C++11)
ATOMIC_FLAG_INIT(C++11)
Memoria pedido
Original:
Memory ordering
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
memory_order(C++11)
kill_dependency(C++11)
atomic_thread_fence(C++11)
atomic_signal_fence(C++11)
 
Defined in header <atomic>
enum memory_order {

    memory_order_relaxed,
    memory_order_consume,
    memory_order_acquire,
    memory_order_release,
    memory_order_acq_rel,
    memory_order_seq_cst

};
(desde C++11)
std::memory_order especifica cómo no-atómicas accesos a memoria se deben pedir en torno a una operación atómica. La razón de esto es que cuando varios subprocesos al mismo tiempo leer y escribir en varias variables en sistemas multi-core, un subproceso podría ver el cambio de valores en un orden diferente que otro hilo ha escrito. También, el orden aparente de cambios puede ser diferente a través de varios subprocesos de lectura. Asegurar que todos los accesos a memoria a las variables atómicas secuencial puede perjudicar el rendimiento en algunos casos. std::memory_order permite especificar las limitaciones exactas que el compilador debe cumplir .
Original:
std::memory_order specifies how non-atomic memory accesses are to be ordered around an atomic operation. The rationale of this is that when several threads simultaneously read and write to several variables on multi-core systems, one thread might see the values change in different order than another thread has written them. Also, the apparent order of changes may be different across several reader threads. Ensuring that all memory accesses to atomic variables are sequential may hurt performance in some cases. std::memory_order allows to specify the exact constraints that the compiler must enforce.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
Es posible especificar el orden de la memoria a medida para cada operación atómica en la biblioteca a través de un parámetro adicional. El valor predeterminado es std::memory_order_seq_cst .
Original:
It's possible to specify custom memory order for each atomic operation in the library via an additional parameter. The default is std::memory_order_seq_cst.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

Contenido

[editar] Constantes

Defined in header <atomic>
Valor
Original:
Value
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
Explanation
memory_order_relaxed
' 'Relajado' pedido: no hay restricciones en la reordenación de accesos a memoria alrededor de la variable atómica .
Original:
Relaxed ordering: there are no constraints on reordering of memory accesses around the atomic variable.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
memory_order_consume
'Consumir' operación: no se lee en el subproceso actual depende del valor cargado en ese momento pueden ser reordenadas antes de esta carga. Esto asegura que escribe para variables dependientes en otros hilos que liberan la misma variable atómica son visibles en el subproceso actual. En la mayoría de las plataformas, esto afecta a la optimización de compilador sólo .
Original:
Consume operation: no reads in the current thread dependent on the value currently loaded can be reordered before this load. This ensures that writes to dependent variables in other threads that release the same atomic variable are visible in the current thread. On most platforms, this affects compiler optimization only.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
memory_order_acquire
'Adquirir' operación: no se lee en el subproceso actual se pueden reordenar antes de esta carga. Esto asegura que todas las escrituras en otros hilos que liberan la misma variable atómica son visibles en el subproceso actual .
Original:
Acquire operation: no reads in the current thread can be reordered before this load. This ensures that all writes in other threads that release the same atomic variable are visible in the current thread.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
memory_order_release
Operación' 'Release': no ​​escribe en el subproceso actual se pueden reordenar después de esta tienda. Esto asegura que todas las escrituras en el subproceso actual son visibles en otros hilos que adquieren la misma variable atómica .
Original:
Release operation: no writes in the current thread can be reordered after this store. This ensures that all writes in the current thread are visible in other threads that acquire the same atomic variable.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
memory_order_acq_rel
Operación 'Acquire-release': no ​​se lee en el subproceso actual se pueden reordenar antes de esta carga, así como no escribe en el subproceso actual se pueden reordenar después de esta tienda. La operación es de lectura-modificación-escritura de la operación. Se garantiza que todas las escrituras en otros hilos que liberan la variable atómica mismo son visibles antes de la modificación y la modificación es visible en otros hilos que adquieren la variable atómica mismo .
Original:
Acquire-release operation: no reads in the current thread can be reordered before this load as well as no writes in the current thread can be reordered after this store. The operation is read-modify-write operation. It is ensured that all writes in another threads that release the same atomic variable are visible before the modification and the modification is visible in other threads that acquire the same atomic variable.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
memory_order_seq_cst
Ordenamiento secuencial. La operación tiene la misma semántica que adquieren operación de liberación, y, además, tiene operación secuencialmente orden coherente .
Original:
Sequential ordering. The operation has the same semantics as acquire-release operation, and additionally has sequentially-consistent operation ordering.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

[editar] Relajado orden

Operaciones atómicas etiquetados std::memory_order_relaxed presentan las propiedades siguientes:
Original:
Atomic operations tagged std::memory_order_relaxed exhibit the following properties:
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
  • No ordenación de accesos a la memoria otros se garantiza que sea. Esto significa que no es posible sincronizar varios hilos utilizando la variable atómica .
    Original:
    No ordering of other memory accesses is ensured whatsoever. This means that it is not possible to synchronize several threads using the atomic variable.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • Lee y escribe en la variable atómica en sí están ordenados. Una vez que el hilo lee un valor, una lectura posterior por el mismo hilo del mismo objeto no se puede dar un valor antes .
    Original:
    Reads and writes to the atomic variable itself are ordered. Once a thread reads a value, a subsequent read by the same thread from the same object can not yield an earlier value.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
Por ejemplo, con x y y inicialmente cero,
Original:
For example, with x and y initially zero,
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

// Thread 1:
r1 = y.load(memory_order_relaxed);
x.store(r1, memory_order_relaxed);
// Thread 2:
r2 = x.load(memory_order_relaxed);
y.store(42, memory_order_relaxed);

se le permite producir r1 == r2 == 42 .
Original:
is allowed to produce r1 == r2 == 42.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

[editar] Release-Consumir pedido

Si un almacén atómico está etiquetado std::memory_order_release y una carga atómica a partir de la misma variable se etiqueta std::memory_order_consume, las operaciones de exhibir las propiedades siguientes:
Original:
If an atomic store is tagged std::memory_order_release and an atomic load from the same variable is tagged std::memory_order_consume, the operations exhibit the following properties:
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
  • No se escribe en el subproceso de escritura se pueden reordenar después de que el almacén nuclear
    Original:
    No writes in the writer thread can be reordered after the atomic store
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • No se lee o escribe en función del valor recibido de carga atómica puede ser reordenado antes de la carga atómica. "Depende de" significa que la dirección o el valor se calcula a partir del valor de la variable atómica. Esta forma de sincronización entre los hilos que se conoce como "ordenamiento dependencia" .
    Original:
    No reads or writes dependent on the value received from atomic load can be reordered before the atomic load. "Dependent on" means that the address or value is computed from the value of the atomic variable. This form of synchronization between threads is known as "dependency ordering".
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • La sincronización se establece únicamente entre los hilos liberar' y consume la variable atómica mismo. Otras hebras pueden ver orden diferente de accesos a memoria que uno o ambos de los hilos sincronizados .
    Original:
    The synchronization is established only between the threads releasing and consuming the same atomic variable. Other threads can see different order of memory accesses than either or both of the synchronized threads.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • La sincronización es transitivo. Es decir, si tenemos la siguiente situación:
    Original:
    The synchronization is transitive. That is, if we have the following situation:
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • Tema A libera variable atómica a .
    Original:
    Thread A releases atomic variable a.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • Tema B consume variable atómica a .
    Original:
    Thread B consumes atomic variable a.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • Variable atómica b depende a .
    Original:
    Atomic variable b is dependent on a.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • Tema B variable de lanzamientos atómica b .
    Original:
    Thread B releases atomic variable b.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • Tema C consume o adquiere variable atómica b .
    Original:
    Thread C consumes or acquires atomic variable b.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
Entonces no sólo A y B o B y C están sincronizados, pero A y C también. Es decir, todas las escrituras por el hilo A que se pusieron en marcha antes del lanzamiento de A se garantiza que se completa una vez que hilo C observa que la tienda b .
Original:
Then not only A and B or B and C are synchronized, but A and C also. That is, all writes by the thread A that were launched before the release of a are guaranteed to be completed once thread C observes the store to b.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
En todas las CPU de la corriente principal, distinto de DEC Alpha, ordenamiento dependencia es automático, no hay instrucciones de CPU adicionales se emiten por este modo de sincronización, sólo ciertas optimizaciones del compilador se ven afectados (por ejemplo, el compilador está prohibido realizar cargas especulativas sobre los objetos que están involucrados en la dependencia de la cadena)
Original:
On all mainstream CPUs, other than DEC Alpha, dependency ordering is automatic, no additional CPU instructions are issued for this synchronization mode, only certain compiler optimizations are affected (e.g. the compiler is prohibited from performing speculative loads on the objects that are involved in the dependency chain)
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

[editar] Suelte secuencia

Si algunos atómico es liberado en la tienda y varios otros hilos realizar leer-modificar-escribir las operaciones en que atómica, una "secuencia de liberación" se forma: todos los hilos que llevan a cabo la lectura-modificación-escritura en el mismo atómica sincronizar con la primera rosca y entre sí, incluso si no tienen semántica memory_order_release. Esto hace que un solo productor - consumidor situaciones posibles múltiples sin imponer sincronización innecesaria entre los hilos individuales de los consumidores .
Original:
If some atomic is store-released and several other threads perform read-modify-write operations on that atomic, a "release sequence" is formed: all threads that perform the read-modify-writes to the same atomic synchronize with the first thread and each other even if they have no memory_order_release semantics. This makes single producer - multiple consumers situations possible without imposing unnecessary synchronization between individual consumer threads.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

[editar] Suelte-Adquirir el pedido

Si un almacén atómico está etiquetado std::memory_order_release y una carga atómica a partir de la misma variable se etiqueta std::memory_order_acquire, las operaciones de exhibir las propiedades siguientes:
Original:
If an atomic store is tagged std::memory_order_release and an atomic load from the same variable is tagged std::memory_order_acquire, the operations exhibit the following properties:
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
  • No se escribe en el subproceso de escritura se pueden reordenar después de que el almacén nuclear
    Original:
    No writes in the writer thread can be reordered after the atomic store
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • No se lee en el lector de hilo puede ser reordenado antes de la carga atómica .
    Original:
    No reads in the reader thread can be reordered before the atomic load.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • La sincronización se establece únicamente entre los hilos liberar y' adquirir la variable atómica mismo. Otras hebras pueden ver orden diferente de accesos a memoria que uno o ambos de los hilos sincronizados .
    Original:
    The synchronization is established only between the threads releasing and acquiring the same atomic variable. Other threads can see different order of memory accesses than either or both of the synchronized threads.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • La sincronización es transitivo. Es decir, si tenemos la siguiente situación:
    Original:
    The synchronization is transitive. That is, if we have the following situation:
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • Tema A libera variable atómica a .
    Original:
    Thread A releases atomic variable a.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • Tema B consume variable atómica a .
    Original:
    Thread B consumes atomic variable a.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • Tema B variable de lanzamientos atómica b .
    Original:
    Thread B releases atomic variable b.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • Tema C consume o adquiere variable atómica b .
    Original:
    Thread C consumes or acquires atomic variable b.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
Entonces no sólo A y B o B y C están sincronizados, pero A y C también. Es decir, todas las escrituras por el hilo A que se pusieron en marcha antes del lanzamiento de A se garantiza que se completa una vez que hilo C observa que la tienda b .
Original:
Then not only A and B or B and C are synchronized, but A and C also. That is, all writes by the thread A that were launched before the release of a are guaranteed to be completed once thread C observes the store to b.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
En los sistemas fuertemente ordenadas (x86, SPARC, mainframe IBM), la liberación adquirir pedido es automático. No hay instrucciones de CPU adicionales se emiten por este modo de sincronización, sólo ciertas optimizaciones del compilador se ven afectados (por ejemplo, el compilador está prohibido desplazarse no atómicas tiendas más allá de la tienda atómico-relase o que no sea de cargas atómicas antes de la carga atómica adquirir)
Original:
On strongly-ordered systems (x86, SPARC, IBM mainframe), release-acquire ordering is automatic. No additional CPU instructions are issued for this synchronization mode, only certain compiler optimizations are affected (e.g. the compiler is prohibited from moving non-atomic stores past the atomic store-relase or perform non-atomic loads earlier than the atomic load-acquire)
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

[editar] Secuencialmente consistente pedido

Si un almacén atómico y una está etiquetado std::memory_order_seq_cst y una carga atómica a partir de la misma variable se etiqueta std::memory_order_seq_cst, entonces las operaciones presentan las propiedades siguientes:
Original:
If an atomic store and an is tagged std::memory_order_seq_cst and an atomic load from the same variable is tagged std::memory_order_seq_cst, then the operations exhibit the following properties:
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
  • No se escribe en el subproceso de escritura se pueden reordenar después de que el almacén nuclear
    Original:
    No writes in the writer thread can be reordered after the atomic store
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • No se lee en el lector de hilo puede ser reordenado antes de la carga atómica .
    Original:
    No reads in the reader thread can be reordered before the atomic load.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
  • La sincronización se establece entre todas las operaciones atómicas etiquetados std::memory_order_seq_cst. Todas las roscas con tal operación atómica ver el mismo orden de los accesos a memoria .
    Original:
    The synchronization is established between all atomic operations tagged std::memory_order_seq_cst. All threads using such atomic operation see the same order of memory accesses.
    The text has been machine-translated via Google Translate.
    You can help to correct and verify the translation. Click here for instructions.
Ordenamiento secuencial es necesario para muchas diversas situaciones de consumo varios productores y en el que todos los consumidores deben observar las acciones de todos los productores que ocurren en el mismo orden .
Original:
Sequential ordering is necessary for many multiple producer-multiple consumer situations where all consumers must observe the actions of all producers occurring in the same order.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.
Ordenamiento secuencial total requiere una valla llena la memoria de instrucciones de la CPU en todos los sistemas multi-core. Esto puede convertirse en un cuello de botella, ya que obliga a todos los accesos a memoria se propaguen a cada hilo .
Original:
Total sequential ordering requires a full memory fence CPU instruction on all multi-core systems. This may become a performance bottleneck since it forces all memory accesses to propagate to every thread.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

[editar] Relación con volátil

{{{1}}}
Original:
{{{2}}}
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

[editar] Ejemplos

[editar] std::memory_order_relaxed

El siguiente ejemplo muestra una tarea (actualización de un contador global) que requiere de atomicidad, pero no hay limitaciones de pedido ya no atómica, la memoria no está involucrado .
Original:
The following example demonstrates a task (updating a global counter) that requires atomicity, but no ordering constraints since non-atomic memory is not involved.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

#include <vector>
#include <iostream>
#include <thread>
#include <atomic>
 
std::atomic<int> cnt = ATOMIC_VAR_INIT(0);
 
void f()
{
    for(int n = 0; n < 1000; ++n) {
        cnt.fetch_add(1, std::memory_order_relaxed);
    }
}
 
int main()
{
    std::vector<std::thread> v;
    for(int n = 0; n < 10; ++n) {
        v.emplace_back(f);
    }
    for(auto& t : v) {
        t.join();
    }
    std::cout << "Final counter value is " << cnt << '\n';
}

Output:

Final counter value is 10000

[editar] std::memory_order_release and std::memory_order_consume

Este ejemplo demuestra la dependencia-ordenó sincronización: el de datos entero no está relacionado con el puntero a una cadena por una relación de dependencia de datos, por lo que su valor no está definido en el consumidor .
Original:
This example demonstrates dependency-ordered synchronization: the integer data is not related to the pointer to string by a data-dependency relationship, thus its value is undefined in the consumer.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

#include <thread>
#include <atomic>
#include <cassert>
#include <string>
 
std::atomic<std::string*> ptr;
int data;
 
void producer()
{
    std::string* p  = new std::string("Hello");
    data = 42;
    ptr.store(p, std::memory_order_release);
}
 
void consumer()
{
    std::string* p2;
    while (!(p2 = ptr.load(std::memory_order_consume)))
        ;
    assert(*p2 == "Hello"); // never fires
    assert(data == 42); // may or may not fire
}
 
int main()
{
    std::thread t1(producer);
    std::thread t2(consumer);
    t1.join(); t2.join();
}


[editar] std::memory_order_release and memory_order_acquire

Mutex, colas concurrentes, y otras situaciones de productores y consumidores exigen liberación de pedido en el hilo editor y adquirir pedido en el hilo de los consumidores. Este patrón establece la sincronización de pares entre hilos .
Original:
Mutexes, concurrent queues, and other producer-consumer situations require release ordering in the publisher thread and acquire ordering in the consumer thread. This pattern establishes pairwise synchronization between threads.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

#include <thread>
#include <atomic>
#include <cassert>
#include <string>
 
std::atomic<std::string*> ptr;
int data;
 
void producer()
{
    std::string* p  = new std::string("Hello");
    data = 42;
    ptr.store(p, std::memory_order_release);
}
 
void consumer()
{
    std::string* p2;
    while (!(p2 = ptr.load(std::memory_order_acquire)))
        ;
    assert(*p2 == "Hello"); // never fires
    assert(data == 42); // never fires
}
 
int main()
{
    std::thread t1(producer);
    std::thread t2(consumer);
    t1.join(); t2.join();
}


[editar] std::memory_order_acq_rel

El siguiente ejemplo demuestra transitivo liberar a adquirir pedidos a través de tres hilos
Original:
The follow example demonstrates transitive release-acquire ordering across three threads
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

#include <thread>
#include <atomic>
#include <cassert>
#include <vector>
 
std::vector<int> data;
std::atomic<int> flag = ATOMIC_VAR_INIT(0);
 
void thread_1()
{
    data.push_back(42);
    flag.store(1, std::memory_order_release);
}
 
void thread_2()
{
    int expected=1;
    while (!flag.compare_exchange_strong(expected, 2, std::memory_order_acq_rel)) {
        expected = 1;
    }
}
 
void thread_3()
{
    while (flag.load(std::memory_order_acquire) < 2)
        ;
    assert(data.at(0) == 42); // will never fire
}
 
int main()
{
    std::thread a(thread_1);
    std::thread b(thread_2);
    std::thread c(thread_3);
    a.join(); b.join(); c.join();
}


[editar] std::memory_order_seq_cst

Este ejemplo muestra una situación en la orden secuencial es necesario. Cualquier otro orden puede desencadenar la aserción, ya que sería posible que los hilos c y d para observar los cambios en las atómica x y y en orden opuesto .
Original:
This example demonstrates a situation where sequential ordering is necessary. Any other ordering may trigger the assert because it would be possible for the threads c and d to observe changes to the atomics x and y in opposite order.
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

#include <thread>
#include <atomic>
#include <cassert>
 
std::atomic<bool> x = ATOMIC_VAR_INIT(false);
std::atomic<bool> y = ATOMIC_VAR_INIT(false);
std::atomic<int> z = ATOMIC_VAR_INIT(0);
 
void write_x()
{
    x.store(true, std::memory_order_seq_cst);
}
 
void write_y()
{
    y.store(true, std::memory_order_seq_cst);
}
 
void read_x_then_y()
{
    while (!x.load(std::memory_order_seq_cst))
        ;
    if (y.load(std::memory_order_seq_cst)) {
        ++z;
    }
}
 
void read_y_then_x()
{
    while (!y.load(std::memory_order_seq_cst))
        ;
    if (x.load(std::memory_order_seq_cst)) {
        ++z;
    }
}
 
int main()
{
    std::thread a(write_x);
    std::thread b(write_y);
    std::thread c(read_x_then_y);
    std::thread d(read_y_then_x);
    a.join(); b.join(); c.join(); d.join();
    assert(z.load() != 0);  // will never happen
}