2012-09-09 21 views
17

Sklepy są operacjami zwolnienia, a obciążenia są operacjami nabycia dla obu. Wiem, że memory_order_seq_cst ma nakładać dodatkową całkowitą kolejność dla wszystkich operacji, ale nie udało mi się zbudować przykładu, w którym nie jest tak, jeśli wszystkie memory_order_seq_cst zostaną zastąpione przez memory_order_acq_rel.Czym różnią się parametry memory_order_seq_cst i memory_order_acq_rel?

Czy coś mi umknęło, czy różnica jest tylko efektem dokumentacji, tj. Należy użyć memory_order_seq_cst, jeśli ktoś nie chce grać z bardziej zrelaksowanym modelem i używać memory_order_acq_rel, gdy ogranicza zrelaksowany model?

Odpowiedz

18

http://en.cppreference.com/w/cpp/atomic/memory_order ma dobry przykład na dole, który działa tylko z memory_order_seq_cst. Zasadniczo memory_order_acq_rel zapewnia kolejność odczytu i zapisu w odniesieniu do zmiennej atomowej, podczas gdy memory_order_seq_cst zapewnia globalne porządkowanie odczytu i zapisu. Oznacza to, że sekwencyjnie spójne operacje są widoczne w tej samej kolejności we wszystkich wątkach.

Przykład sprowadza się do tego:

bool x= false; 
bool y= false; 
int z= 0; 

a() { x= true; } 
b() { y= true; } 
c() { while (!x); if (y) z++; } 
d() { while (!y); if (x) z++; } 

// kick off a, b, c, d, join all threads 
assert(z!=0); 

Operacje na z są strzeżone przez dwóch zmiennych atomowych, a nie jeden, więc nie można użyć semantykę nabywać uwalnianiu egzekwować że z zawsze jest zwiększany.

+0

Nie rozumiem, dlaczego 'x = true, y = true; c(); d()' nie jest możliwe? To powinno spowodować, że będzie to 0. Również nie wiem, dlaczego otrzymuję 2 dużo jako wyniki. –

+1

@ acidzombie24, nawet w tym przypadku 'z' będzie 2. – MSN

+0

Zepsułem, źle odczytałem kod. To ma teraz sens. –

Powiązane problemy