La coda MPSC (Multiple Producer Single Consumer) senza blocco Multiplo è uno degli algoritmi di lock-free più facili da implementare.
L'implementazione di base richiede una semplice lista di collegamenti separati (SList) con solo push() e flush(). Le funzioni sono disponibili nell'API di Windows come InterlockedFlushSList() e InterlockedPushEntrySList(), ma sono molto semplici da eseguire autonomamente.
Più oggetti push() del produttore sullo SList utilizzando un CAS (confronta-e-swap interbloccato).
Il singolo consumatore esegue un flush() che scambia la testa dello SList con un valore NULL utilizzando un XCHG (scambio interbloccato). Il consumatore ha quindi un elenco di articoli nell'ordine inverso.
Per elaborare gli articoli in ordine, è necessario semplicemente invertire l'elenco restituito da flush() prima di elaborarlo. Se non ti interessa l'ordine, puoi semplicemente percorrere immediatamente l'elenco per elaborarlo.
Due note se si tira le proprie funzioni:
1) Se siete su un sistema con una debole ordinazione di memoria (cioè PowerPC), è necessario mettere un "rilascio barriera di memoria" all'inizio della spinta() e una "barriera della memoria dell'acquario" alla fine della funzione flush().
2) È possibile rendere le funzioni notevolmente semplificate e ottimizzate poiché il problema ABA con gli SLIS si verifica durante la funzione pop(). Non puoi avere problemi ABA con una SList se usi solo push() e flush(). Ciò significa che è possibile implementarlo come un singolo puntatore molto simile al codice senza blocco e non è necessario un contatore di sequenza di prevenzione ABA.
è necessario acquisire/rilasciare barriere di memoria sulle impostazioni ready = true/false e owned = false. Così come all'interno di CompareAndSwap, ma di solito è solo una parte della funzione. – tony
Questo dipende interamente dalle regole di ordinamento della memoria dell'architettura.Se le scritture non vengono riordinate rispetto ad altre scritture emesse dallo stesso processore (che è comune), allora la barriera di memoria con 'CompareAndSwap' stessa è sufficiente per la correttezza. – caf