2012-09-09 14 views
17

I negozi sono operazioni di rilascio e i carichi sono operazioni di acquisizione per entrambi. So che lo memory_order_seq_cst intende imporre un ulteriore ordinamento totale per tutte le operazioni, ma non riesco a creare un esempio in cui non è il caso se tutti gli memory_order_seq_cst vengono sostituiti da memory_order_acq_rel.In che modo memory_order_seq_cst e memory_order_acq_rel differiscono?

Mi manca qualcosa, o la differenza è solo un effetto di documentazione, cioè si dovrebbe usare memory_order_seq_cst se si intende non giocare con un modello più rilassato e usare memory_order_acq_rel quando si vincola il modello rilassato?

risposta

18

http://en.cppreference.com/w/cpp/atomic/memory_order ha un buon esempio in basso che funziona solo con memory_order_seq_cst. In sostanza, memory_order_acq_rel fornisce gli ordini di lettura e scrittura relativi alla variabile atomica, mentre memory_order_seq_cst fornisce ordini di lettura e scrittura a livello globale. Cioè, le operazioni sequenzialmente coerenti sono visibili nello stesso ordine attraverso tutti i thread.

L'esempio si riduce a questo:

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); 

Operazioni su z sono sorvegliate da due variabili atomiche, non uno, quindi non è possibile utilizzare la semantica acquisire a rilascio per imporre che z viene sempre incrementato.

+0

Non capisco perché 'x = vero; y = vero; c(); d()' non è possibile? Questo dovrebbe far sì che sia 0. Inoltre non so perché ottengo 2 molto come risultato. –

+1

@ acidzombie24, anche in questo caso, 'z' sarà 2. – MSN

+0

Ho incasinato, ho letto male il codice. Questo ha perfettamente senso ora –

Problemi correlati