2014-06-30 12 views
6

Sto leggendo C++ Concorrenza in azione di Anthony Williams, e non capisco la sua implementazione push della classe lock_free_stack.C++ blocco 11 lock libero

Perché mai l'atomico load non è nel ciclo while? La ragione per cui ha dato è:

Voi dunque non c'è bisogno di ricaricare la testa ogni volta attraverso il ciclo, perché il compilatore che fa per voi.

Ma non capisco l'immagine. Qualcuno può fare luce su questo?

template<typename T> 
class lock_free_stack 
{ 
private: 
struct node 
{ 
    T data; 
    node* next; 
    node(T const& data_) : 
    data(data_) 
    {} 
}; 
std::atomic<node*> head; 
public: 
void push(T const& data) 
{ 
    node* const new_node=new node(data); 
    new_node->next=head.load(); 
    while(!head.compare_exchange_weak(new_node->next,new_node)); 
} 
}; 

risposta

6

La chiave è nell'interfaccia di compare_exchange_weak, che in questo caso richiede 2 argomenti. Il primo è un riferimento al valore atteso e il secondo è il desiderato. Se il valore corrente dell'atomico non è uguale all'input previsto, restituirà false e l'input previsto verrà impostato sul valore corrente.

Quindi in questo caso, ciò che sta facendo è impostare new_node->next = head. Quindi, sta dicendo che se lo head è uguale a new_node->next, scambialo in head. Se non è più quel valore, utilizza il riferimento a new_node->next per assegnargli il valore corrente di head. Poiché ogni iterazione del ciclo fallisce, sostituisce anche new_node->next con il valore corrente di head, non vi è alcuna lettura da duplicare nel corpo del ciclo.

+0

Sì, ha perfettamente senso ora. Grazie! – Stringer

3

Dalla documentazione di compare_exchange_weak:

Atomicamente confronta il valore memorizzato in * questo con il valore di atteso, e se queste sono uguali, sostituisce il primo con desiderato (esegue lettura-modifica-scrittura funzionamento). In caso contrario, carica il valore effettivo memorizzato in * this in previsto (esegue l'operazione di caricamento).

Come si vede, altrimenti il valore effettivo della head viene caricato in attesa.