我正在发出多个http请求:
type item struct{
me []byte
}
items := getItems()
for _, me := range items {
me.save()
}
为了高效地执行go rutine,我的第一种方法是使其变得像go rutine池:
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
代替 channel : 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 rutine来查找bandwidht可以处理的max go rutine,我的代码越来越大,我尝试这样做:
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 {
//???????????????
}
}
但是我不确定如何作为最后一种方法
还请记住,“从 channel slice 中选择”是一个已经问过的问题,但只有
select
正在监听哪个 channel 先到达时,他们的答案才对,在我的情况下,我希望Select
发送任何空闲 channel ,因此有所不同 最佳答案
您可以使用reflect.Select,使用SelectCase
创建一片Dir=SelectSend
结构,如下所示:
max:=7
var channels []chan item
for i:=0;i<max;i++{
channel=make(chan item)
channels=append(channels,channel)
}
for _, me := range items {
cases := make([]reflect.SelectCase, max)
for j := 0; j < max; j++ {
cases[j] = reflect.SelectCase{
Dir: reflect.SelectSend,
Chan: reflect.ValueOf(channels[j]),
Send: reflect.ValueOf(me)
}
}
reflect.Select(cases)
}