Tôi đang cố gắng viết một danh sách liên kết đơn lẻ miễn phí khóa. Sự nhất quán cuối cùng không phải là một vấn đề (ai đó đi qua một danh sách có thể chứa các mục không chính xác).Cố gắng viết một danh sách liên kết đơn lẻ không khóa, gặp sự cố khi xóa
Tôi nghĩ rằng tôi có quyền thêm mục (lặp và Interlocked.CompareExchange
).
Nhưng tôi không thể tìm ra cách xóa nút (bất kỳ vị trí nào trong danh sách) vì tôi phải lấy mục trước và họ đặt trường Next
của nó thành trường hiện tại là Next
.
class Node
{
Node Next;
object Value;
}
class SinglyLinkedList
{
Root _root;
public void Add(object value)
{}
public void Remove(object value)
{}
}
tức
a -> b -> c
để
a -> c
Pseudo mã:
Node prev;
Node node = _root;
while (node.Value != nodeValue)
{
prev = node;
node = node.Next;
}
prev.Next = node.Next;
làm thế nào để làm cho đây là một hoạt động nguyên tử (I E. đảm bảo rằng prev.Next = node.Next
được gọi mà không cần tiếp theo hoặc bị loại bỏ ở giữa bởi một chuỗi khác)?
Tôi có thể sử dụng ReaderWriterLockSlim
thay vào đó, nhưng tôi thấy vấn đề này thú vị vì tôi biết rằng có tồn tại các danh sách được liên kết miễn phí khóa.
mối quan tâm của tôi:
Sau đây có thể xảy ra nếu các chủ đề hiện tại đang lơ lửng giữa vòng lặp và sự phân công:
prev
bản thân có thể đã bị loại bỏ bởi thread khác.node
có thể đã bị xóa bởi một chuỗi khác.Node.Next
có thể đã bị loại bỏ
Bạn đã xem Interlocked.CompareExchange (http://msdn.microsoft.com/en-us/library/system.threading.interlocked.compareexchange%28v=vs.71%29.aspx) chưa? Bạn có thể cập nhật prev với node.next nếu prev vẫn có giá trị ban đầu. –
@JeffPaquette no. cả hai 'node.Next' và' prev.Next' có thể đã được thay đổi bởi 'Add()' hoặc một 'Remove()' hoạt động khác. Vì vậy, so sánh chỉ 'prev' sẽ không giúp đỡ. – jgauffin
Nếu bạn cần một danh sách liên kết miễn phí được liên kết gấp đôi, tôi có thể đề nghị bạn triển khai C# thuần túy dựa trên giấy của Sundell và Tsigas. https://github.com/2i/LockFreeDoublyLinkedList – ominug