使用Go 1.19 atomic.Pointer实现无锁队列遇数据竞态问题求助
无锁队列实现的数据竞态问题排查
我尝试实现Michael和Scott提出的无锁队列,采用Go 1.19引入的atomic.Pointer类型,但应用中出现了数据竞态问题。以下是我的实现代码:
package queue import ( "errors" "sync/atomic" ) // LockfreeQueue represents a FIFO structure with operations to enqueue // and dequeue generic values. type LockFreeQueue[T any] struct { head atomic.Pointer[node[T]] tail atomic.Pointer[node[T]] } // node represents a node in the queue type node[T any] struct { value T next atomic.Pointer[node[T]] } // newNode creates and initializes a node func newNode[T any](v T) *node[T] { return &node[T]{value: v} } // NewQueue creates and initializes a LockFreeQueue func NewLockFreeQueue[T any]() *LockFreeQueue[T] { var head atomic.Pointer[node[T]] var tail atomic.Pointer[node[T]] n := &node[T]{} head.Store(n) tail.Store(n) return &LockFreeQueue[T]{ head: head, tail: tail, } } // Enqueue adds a value to the queue func (q *LockFreeQueue[T]) Enqueue(v T) { n := newNode(v) for { tail := q.tail.Load() next := tail.next.Load() if tail == q.tail.Load() { if next == nil { if tail.next.CompareAndSwap(next, n) { q.tail.CompareAndSwap(tail, n) return } } else { q.tail.CompareAndSwap(tail, next) } } } } // Dequeue removes a value from the queue func (q *LockFreeQueue[T]) Dequeue() (T, error) { for { head := q.head.Load() tail := q.tail.Load() next := head.next.Load() if head == q.head.Load() { if head == tail { if next == nil { return head.value, errors.New("queue is empty") } q.tail.CompareAndSwap(tail, next) } else { v := next.value if q.head.CompareAndSwap(head, next) { return v, nil } } } } } // Check if the queue is empty. func (q *LockFreeQueue[T]) IsEmpty() bool { return q.head.Load() == q.tail.Load() }
我找到另一款可正常运行且无数据竞态的无锁队列实现,但无法明确两者的差异,恳请提供帮助与反馈。
内容的提问来源于stack exchange,提问作者Manuel Martinez
相关产品推荐
相关产品推荐

