从频道切片中选择(发送到免费频道)?

时间:2019-03-10 22:40:14

标签: go channel

我正在发出多个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收听发送任何免费频道,因此有所不同

2 个答案:

答案 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()
}