【发布时间】:2019-08-01 06:01:34
【问题描述】:
我正在发出多个 http 请求:
type item struct{
me []byte
}
items := getItems()
for _, me := range items {
me.save()
}
为了有效地做到这一点,我用 go rutines 来做,我的第一个方法是让它像一个 go rutines 池:
items := getItems()
var wg sync.WaitGroup
wg.Add(len(items))
for _, me := range items {
go func(me item) {
me.save()
wg.Done()
}(me)
}
wg.Wait()
但他们都尝试同时发出 http 请求,其中一些失败,因为我的带宽无法处理所有这些请求。
所以我尝试使用select 代替频道:
channel1 := make(chan item)
channel2 := make(chan item)
channel3 := make(chan item)
var wg sync.WaitGroup
items := getItems()
wg.Add(len(items))
go func() {
for me := range channel1 {
me.save()
wg.Done()
}
}()
go func() {
for me := range channel2 {
me.save()
wg.Done()
}
}()
go func() {
for me := range channel3 {
me.save()
wg.Done()
}
}()
for _, me := range items {
select {
case channel1 <- me:
case channel2 <- me:
case channel3 <- me:
}
}
但是添加更多的 go rutines 以找到我的带宽可以处理的最大 go rutines,我的代码变得越来越大,我尝试这样做:
max:=7
var channels []chan item
for i:=0;i<max;i++{
channel=make(chan item)
channels=append(channels,channel)
}
for _, me := range items {
select {
//???????????????
}
}
但我不确定如何将其作为最后一种方法
还请记住,“从频道片段中选择”是一个已经提出的问题,但他们的答案只有在 select 正在监听哪个频道先到达时,在我的情况下,我希望 Select 发送任何免费频道,所以不一样
【问题讨论】:
-
这是一种……不寻常的实现工作池的方式。为什么不是“标准”方式:一个任务队列,它是一个 [缓冲] 通道和几个工作 goroutine?
-
我试过了,但我做不到,你能举个例子吗?
-
是的,我正在努力寻找一篇关于我不久前阅读的主题的好博文。
-
啊,在这里,看看:marcio.io/2015/07/…。看来作者确实被频道迷住了,但在 cmets 中也有一些很好的提示。