Select 来自部分频道(发送到免费频道)?
Select from slice of channels(sending to a free channel)?
我正在发出多个 http 请求:
type item struct{
me []byte
}
items := getItems()
for _, me := range items {
me.save()
}
为了有效地做到这一点,我使用 go 例程来做,我的第一个方法是让它像一个 go 例程池:
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 例程以找到我的带宽可以处理的最大 go 例程,我的代码变得越来越大,我尝试这样做:
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 from slice of channels" 是一个已经问过的问题,但他们的答案只是在 select
正在收听哪个频道先到达时,在我的情况下,我希望 Select
发送任何免费频道,所以它是不同的
您可以使用 reflect.Select,用 Dir=SelectSend
创建一个 SelectCase
结构的切片,如下所示:
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)
}
我的方法有误,答案很简单
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()
}
我正在发出多个 http 请求:
type item struct{
me []byte
}
items := getItems()
for _, me := range items {
me.save()
}
为了有效地做到这一点,我使用 go 例程来做,我的第一个方法是让它像一个 go 例程池:
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 例程以找到我的带宽可以处理的最大 go 例程,我的代码变得越来越大,我尝试这样做:
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 from slice of channels" 是一个已经问过的问题,但他们的答案只是在 select
正在收听哪个频道先到达时,在我的情况下,我希望 Select
发送任何免费频道,所以它是不同的
您可以使用 reflect.Select,用 Dir=SelectSend
创建一个 SelectCase
结构的切片,如下所示:
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)
}
我的方法有误,答案很简单 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()
}