Sto provando a scrivere una lista di link separati. La coerenza finale non è un problema (qualcuno che attraversa una lista che potrebbe contenere articoli non corretti).Cercando di scrivere una lista concatenata non bloccata, guai con la rimozione
Penso di aver ottenuto l'elemento aggiuntivo corretto (looping e Interlocked.CompareExchange
).
Ma non riesco a capire come rimuovere i nodi (in qualsiasi punto dell'elenco) poiché devo ottenere l'elemento precedente e hanno impostato il campo Next
nel campo Next
dei nodi correnti.
class Node
{
Node Next;
object Value;
}
class SinglyLinkedList
{
Root _root;
public void Add(object value)
{}
public void Remove(object value)
{}
}
cioè
a -> b -> c
a
un -> c
Pseudo codice:
Node prev;
Node node = _root;
while (node.Value != nodeValue)
{
prev = node;
node = node.Next;
}
prev.Next = node.Next;
come faccio a fare questa operazione atomica (cioè assicurati che prev.Next = node.Next
venga richiamato senza che next o prev sia rimosso in mezzo da un altro thread)?
Potrei usare invece ReaderWriterLockSlim
, ma ho trovato questo problema interessante perché so che esistono elenchi concatenati bloccati.
mie preoccupazioni:
segue può accadere se il thread corrente è sospeso tra il loop e l'assegnazione:
prev
stessa potrebbero essere stati rimossi da un altro thread.node
potrebbe essere stato rimosso da un altro thread.Node.Next
potrebbe essere rimosso
Hai guardato Interlocked.CompareExchange (http://msdn.microsoft.com/en-us/library/system.threading.interlocked.compareexchange%28v=vs.71%29.aspx)? È possibile aggiornare prev con node.next se prev ha ancora il suo valore originale. –
@JeffPaquette n. sia 'node.Next' che' prev.Next' potrebbero essere stati modificati da 'Add()' o da un'altra operazione 'Remove()'. Quindi confrontare solo prev non aiuterà. – jgauffin
Se hai bisogno di una lista doppiamente linkata senza blocco, potrei consigliarti la mia pura implementazione in C# basata su un articolo di Sundell e Tsigas. https://github.com/2i/LockFreeDoublyLinkedList – ominug