即使队列中还有空间, RingBuffer 的 Offer 也会返回 false (队列已满)
根据文档,rb.Offer 只在队列已满时才返回 false:
// Offer 将提供的项添加到队列中,如果有空间。 如果队列已满,此调用将返回 false。 如果队列已被释放,则将返回错误。
func (rb *RingBuffer) Offer(item interface{}) (bool, error) {
return rb.put(item, true)
}
但是,当通过**并行**调用 `rb.Offer` 向队列添加元素时,即使有足够的空间,也会返回 false。以下测试文件可以重现此问题。package test import ( "sync" "testing" "GitHub.com/Workiva/go-datastructures/queue" ) func TestRingQueueOffer_parallel(t *testing.T) { size := 256 parallelGoroutines := 8 rb := queue.NewRingBuffer(uint64(size * parallelGoroutines)) wg := new(sync.WaitGroup) wg.Add(parallelGoroutines) for i := 0; i < parallelGoroutines; i++ { go func(id int) { defer wg.Done() for el := 1; el <= size; el++ { ok, err := rb.Offer(el) if err != nil { t.Errorf("error in goroutine-%d: %v", id, err) return } if !ok { t.Errorf("queue full before expected on adding %d element, len: %d, cap: %d ", el, rb.Len(), rb.Cap()) } } }(i) } wg.Wait() } 运行上述测试文件后,我得到:
--- FAIL: TestRingQueueOffer_parallel (0.00s)
ring_buffer_test.go:31: queue full before expected on adding 1 element, len: 49, cap: 2048
ring_buffer_test.go:31: queue full before expected on adding 256 element, len: 1391, cap: 2048
ring_buffer_test.go:31: queue full before expected on adding 1 element, len: 1730, cap: 2048
FAIL
FAIL command-line-arguments 0.028s
FAIL内容来源: Workiva/go-datastructures