golang双端链表list remove nil问题

我这个场景是做优先级的任务派发的,因为有几十个厂商,每个厂商还有不同的业务,每个业务也有10个优先级,这样算来整个任务缓冲池里最少又要几百个队列。 这里没用channel,因为channel通道太多,没法很好的做输出。  优先级肯定是有调度器主动去pop数据,这里选择了使用container/list提供的双端列表。 

我的服务主要体现在Push, Pop 类似的操作上,container/list都可以O(1)的时间复杂度。

该文章后续会有更新, 原文地址, http://xiaorui.cc/?p=4809

话题说 list 有个 remove的问题…  你遍历整个链表会发现只会删除第一个,当再次迭代的时候,e.Next() == nil 空值,跳出循环。。。

for e := l.Front(); e != nil; e = e.Next() {
    l.Remove(e)
}

为什么会出现这个问题,我们可以看下 golang list 关于 remove方法的实现。  e.next = nil 注释是说,为了防止内存泄露…

// remove removes e from its list, decrements l.len, and returns e.
func (l *List) remove(e *Element) *Element {
    e.prev.next = e.next
    e.next.prev = e.prev
    e.next = nil // avoid memory leaks
    e.prev = nil // avoid memory leaks
    e.list = nil
    l.len--
    return e
}

// Remove removes e from l if e is an element of list l.
// It returns the element value e.Value.
func (l *List) Remove(e *Element) interface{} {
    if e.list == l {
        // if e.list == l, l must have been initialized when e was inserted
        // in l or l == nil (e is a zero Element) and l.remove will crash
        l.remove(e)
    }
    return e.Value
}

那么我们该如何解决? 

        var next *list.Element
	task = nil
	next = nil
	pri_list := qname[i]
	for e := pri_list.Queue.Front(); e != nil; e = next {
		next = e.Next()            // 在这里
		fmt.Println(e)
		pri_list.Queue.Remove(e)
		task = e.Value.(*dao.MainTask)
		break
	}
	b.BigLock.Unlock()
	if task == nil {
		continue
	}
	b.FastBuffer <- task
	c += 1

END


大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc