Espaces de noms
Variantes
Affichages
Actions

std::memory_order

De cppreference.com
< cpp‎ | atomic

 
 
Atomique opérations de la bibliothèque
Types
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)
Fonctions
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)
Drapeaux atomiques
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)
Initialisation
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)
Mémoire de la commande
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

};
(depuis C++11)
std::memory_order spécifie comment les accès mémoire non-atomiques sont à commander dans une opération atomique. La raison de ceci est que lorsque plusieurs threads simultanément lire et à écrire à plusieurs variables sur systèmes multi-core, un thread peut vu le changement des valeurs dans un ordre différent qu'un autre thread a écrits. En outre, l'ordre apparent des changements peuvent être différents à travers plusieurs threads de lecture. Veiller à ce que tous les accès à la mémoire de variables atomiques sont séquentielle peut nuire aux performances dans certains cas. std::memory_order permet de spécifier les contraintes exactes que le compilateur doit respecter .
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.
Il est possible de spécifier l'ordre de mémoire personnalisé pour chaque opération atomique dans la bibliothèque via un paramètre supplémentaire. La valeur par défaut est 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.

Sommaire

[modifier] Constantes

Defined in header <atomic>
Valeur
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
Détendu' ordre: il n'y a aucune contrainte sur la réorganisation des accès à la mémoire autour de la variable atomique .
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
'Consommer': pas de lit dans le fil de courant dépend de la valeur actuellement chargé peut être commandé avant cette charge. Cela garantit que les variables dépendantes écrit dans d'autres threads qui libèrent la même variable atomique sont visibles dans le thread courant. Sur la plupart des plates-formes, ce qui affecte l'optimisation du compilateur seulement .
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
'Acquisition': pas de lit dans le thread en cours peuvent être réorganisés avant que cette charge. Cela garantit que toutes les écritures dans d'autres threads qui libèrent la même variable atomique sont visibles dans le thread en cours .
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
Opération 'Release': pas écrit dans le thread courant peuvent être réorganisés après cette boutique. Cela garantit que toutes les écritures dans le thread courant sont visibles dans d'autres threads qui acquièrent la même variable atomique .
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
'Acquisition de libération': pas de lit dans le thread en cours peuvent être réorganisés avant que cette charge ainsi que pas écrit dans le thread courant peuvent être réorganisés après cette boutique. L'opération est de lecture-modification-écriture. Il est veillé à ce que toutes les écritures dans un autre fils qui libèrent la même variable atomique sont visibles avant la modification et la modification est visible dans les autres threads qui acquièrent la même variable atomique .
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
Ordre séquentiel. L'opération a la même sémantique que l'acquisition de libération opération, et a en outre opération séquentielle cohérente commande .
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.

[modifier] Détendu ordre

Les opérations atomiques taggés std::memory_order_relaxed présenter les propriétés suivantes:
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.
  • Aucun ordre d'accès mémoire est assurée autres que ce soit. Cela signifie qu'il n'est pas possible de synchroniser plusieurs threads en utilisant la variable atomique .
    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.
  • Lit et écrit à la variable atomique se sont classés. Une fois qu'un thread lit une valeur, une lecture ultérieure par le même thread du même objet ne peut pas donner une valeur plus tôt .
    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.
Par exemple, avec x et y initialement nul,
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);

est autorisée à produire 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.

[modifier] Consommer libération de la commande

Si un magasin atomique est marqué std::memory_order_release et une charge atomique de la même variable est marqué std::memory_order_consume, les opérations présentent les propriétés suivantes:
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.
  • Aucune écrit dans le thread d'écriture peuvent être réorganisés après le magasin atomique
    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.
  • Pas de lecture ou d'écriture dépendant de la valeur de la charge reçue atomique peut être commandé avant la charge atomique. "En fonction" signifie que l'adresse ou la valeur est calculée à partir de la valeur de la variable atomique. Cette forme de synchronisation entre les threads est connu comme "l'ordre dépendance" .
    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 synchronisation est établie uniquement entre les fils de libérer' et de consommer la même variable atomique. D'autres threads peuvent voir autre ordre d'accès à la mémoire d'un ou des deux des fils synchronisés .
    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 synchronisation est transitive. Autrement dit, si nous avons la situation suivante:
    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.
  • Discussion A libère variable atomique 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.
  • Discussion B consomme variable atomique 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 atomique b est tributaire 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.
  • Discussion B communiqués variable atomique 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.
  • Discussion C consomme ou acquiert variable atomique 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.
Alors, non seulement A et B ou B et C sont synchronisés, mais A et C aussi. Autrement dit, tout écrit par le thread A qui ont été lancées avant la sortie de a sont garantis d'être terminé une fois filet C observe le magasin pour 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.
Sur tous les processeurs grand public, autre que DEC Alpha, l'ordre de la dépendance est automatique, aucune instruction CPU supplémentaires sont émis pour ce mode de synchronisation, seules les optimisations du compilateur certains sont touchés (par exemple, le compilateur est interdit d'exécuter des charges de spéculation sur les objets qui sont impliqués dans le la dépendance de la chaîne)
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.

[modifier] Relâchez séquence

Si certains atomique est sorti en magasin et plusieurs autres threads effectuer de lecture-modification-écriture atomique sur ce, une "séquence libération" est formé: tous les threads qui effectuent la lecture-modification-écriture sur le même atome synchroniser avec le premier filet et l'autre, même si elles n'ont pas de sémantique memory_order_release. Cela rend seul producteur - de multiples situations possibles consommateurs sans imposer de synchronisation inutile entre les threads individuels des consommateurs .
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.

[modifier] Relâchez-Acquérir la commande

Si un magasin atomique est marqué std::memory_order_release et une charge atomique de la même variable est marqué std::memory_order_acquire, les opérations présentent les propriétés suivantes:
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.
  • Aucune écrit dans le thread d'écriture peuvent être réorganisés après le magasin atomique
    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.
  • Aucun lit dans le thread de lecture peuvent être réorganisés avant que la charge atomique .
    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 synchronisation est établie uniquement entre les fils de libérer et' acquisition de la même variable atomique. D'autres threads peuvent voir autre ordre d'accès à la mémoire d'un ou des deux des fils synchronisés .
    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 synchronisation est transitive. Autrement dit, si nous avons la situation suivante:
    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.
  • Discussion A libère variable atomique 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.
  • Discussion B consomme variable atomique 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.
  • Discussion B communiqués variable atomique 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.
  • Discussion C consomme ou acquiert variable atomique 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.
Alors, non seulement A et B ou B et C sont synchronisés, mais A et C aussi. Autrement dit, tout écrit par le thread A qui ont été lancées avant la sortie de a sont garantis d'être terminé une fois filet C observe le magasin pour 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.
Sur les systèmes fortement ordonnées (x86, SPARC, mainframe IBM), libération d'acquérir commande est automatique. Pas d'instructions CPU supplémentaires sont émis pour ce mode de synchronisation, seules les optimisations du compilateur certains sont touchés (par exemple, le compilateur est interdit de se déplacer non-atomiques magasins devant le magasin-relase atomique ou non atomique effectuer des chargements plus tôt que la bombe atomique charge acquérir)
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.

[modifier] Séquentielle cohérente de la commande

Si un magasin atomique et un est marqué std::memory_order_seq_cst et une charge atomique de la même variable est marqué std::memory_order_seq_cst, puis les opérations de présenter les propriétés suivantes:
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.
  • Aucune écrit dans le thread d'écriture peuvent être réorganisés après le magasin atomique
    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.
  • Aucun lit dans le thread de lecture peuvent être réorganisés avant que la charge atomique .
    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 synchronisation est établie entre toutes les opérations atomiques taggés std::memory_order_seq_cst. Tous les threads utilisant de tels opération atomique voir le même ordre d'accès à la mémoire .
    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.
Ordre séquentiel est nécessaire pour de nombreuses multiples situations de consommation producteurs multiples où tous les consommateurs doivent observer les actions de tous les producteurs qui se produisent dans le même ordre .
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.
Totale ordre séquentiel exige une instruction mémoire est pleine clôture CPU sur tous les systèmes multi-core. Cela peut devenir un goulot d'étranglement des performances, car il force tous les accès mémoire se propager à tous les fils .
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.

[modifier] Relations avec les volatiles

{{{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.

[modifier] Exemples

[modifier] std::memory_order_relaxed

L'exemple suivant illustre une tâche (mise à jour un compteur global) qui exige que l'atomicité, mais pas de contraintes d'ordre depuis la mémoire non-atomique n'est pas impliqué .
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';
}

Résultat :

Final counter value is 10000

[modifier] std::memory_order_release and std::memory_order_consume

Cet exemple démontre la dépendance ordonnée synchronisation: les données entier n'est pas liée au pointeur de chaîne par une relation de dépendance de données, donc sa valeur n'est pas définie dans la consommation .
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();
}


[modifier] std::memory_order_release and memory_order_acquire

Les mutex, les files d'attente simultanées et d'autres producteurs-consommateurs situations exigent la libération de commande dans le fil de l'éditeur et d'acquérir de commande dans le thread consommateur. Ce modèle établit la synchronisation entre les threads par paire .
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();
}


[modifier] std::memory_order_acq_rel

L'exemple suivant montre transitive libérer-acquérir l'ordre parmi les trois fils
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();
}


[modifier] std::memory_order_seq_cst

Cet exemple illustre une situation où ordre séquentiel est nécessaire. Toute autre ordre peut déclencher l'affirmer, car il serait possible pour les fils c et d d'observer les modifications apportées aux atomics x et y dans l'ordre inverse .
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
}