简单的并发队列

FPG*_*PGA 0 go

有人可以提一下像Queue一样的缺陷和性能缺陷吗?

type Queue struct {
    sync.Mutex
    Items []interface{}
}

func (q *Queue) Push(item interface{}) {
    q.Lock()
    defer q.Unlock()
    q.Items = append(q.Items, item)
}

func (q *Queue) Pop() interface{} {
    q.Lock()
    defer q.Unlock()
    if len(q.Items) == 0 {
        return nil
    }
    item := q.Items[0]
    q.Items = q.Items[1:]
    return item
}
Run Code Online (Sandbox Code Playgroud)

我也有像PopMany和PushMany这样的方法,而我所关注的是,重新切片那么糟糕吗?

Ric*_*777 6

您可以简单地使用缓冲通道.

var queue = make(chan interface{}, 100)
Run Code Online (Sandbox Code Playgroud)

缓冲区的大小可以根据经验确定足够大,以达到推动率与流行率的高水位标记.理想情况下,它应该不大于此,以避免浪费内存.

实际上,如果相互作用的goroutine由于其他原因没有死锁,则较小的缓冲区大小也将起作用.如果使用较小的缓冲区大小,则通过goroutine时间片引擎(Go运行时的一部分)的运行队列有效地进行排队.(很可能,缓冲区大小为零可能在许多情况下都有效.)

频道允许许多读者goroutines和许多作家goroutines.Go运行时自动处理它们的访问并发性.对信道的所有写入都是交织的,以便成为顺序流.所有读取也是交错的,以它们排队的顺序依次提取值.以下是对此主题的进一步讨论.