我正在发出多个http请求:
type item struct{
me []byte
}
items := getItems()
for _, me := range items {
me.save()
}
为了高效地执行go rutine,我的第一种方法是使其变得像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 rutine来查找bandwidht可以处理的最大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 {
//???????????????
}
}
但是我不确定作为最后一种方法怎么做
还请记住,“从频道切片中选择”是一个已经提出的问题,但只有select
正在收听哪个频道首先到达时才给出答案,在我的情况下,我希望Select
收听发送任何免费频道,因此有所不同
答案 0 :(得分:1)
您可以使用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)
}
答案 1 :(得分:0)
我的方法错误,答案很简单 worker pools
type item struct {
me []byte
}
func worker(canalFiles <-chan item, wg *sync.WaitGroup) {
for file := range canalFiles {
file.save()
wg.Done()
}
}
func main() {
var wg sync.WaitGroup
items := getItems()
wg.Add(len(items))
canalFiles := make(chan item)
for i := 0; i < 8; i++ {
go worker(canalFiles, &wg)
}
for _, file := range items {
canalFiles <- file
}
fmt.Printf("waiting.....")
wg.Wait()
}