无限的 goroutines 直到收到期望的响应
Infinite goroutines until received desired response
我正在尝试在无限循环中启动 goroutine,直到我得到我正在寻找的响应,但是如果我将 for i := 0; i < 10; i++ {}
更改为 for {}
,select
将无法访问。解决这个问题的模式是什么?
package main
import (
"fmt"
"math/rand"
"time"
)
func myFunc() float64 {
c := make(chan float64)
for i := 0; i < 10; i++ {
go func() {
var value float64
value = someOp()
if value > .9 {
c <- value
}
}()
}
// unreachable code the if the for loop above is infinite
for {
select {
case x := <-c:
return x
default:
}
}
}
func someOp() float64 {
rand.Seed(time.Now().UnixNano())
return rand.Float64()
}
func main() {
fmt.Println(myFunc())
}
启动无限数量的 goroutines 通常不是一个好主意。更好的方法是启动固定数量的 goroutine,这些 goroutine 会循环寻找答案。 Return 从这些 goroutines 找到答案时。
func myFunc() float64 {
c := make(chan float64, 1) // Size 1 prevents race between main goroutine and workers
done := make(chan struct{})
defer close(done)
// Start a fixed number of goroutines
for i := 0; i < 10; i++ {
go func() {
for {
select {
case <-done:
// myfunc exited with result, return from this goroutine
return
default:
var value float64
value = someOp()
if value > .9 {
select {
case c <- value:
// This is first goroutine to send a value
default:
// Another goroutine sent a value
}
return
}
}
}
}()
}
return <-c
}
我正在尝试在无限循环中启动 goroutine,直到我得到我正在寻找的响应,但是如果我将 for i := 0; i < 10; i++ {}
更改为 for {}
,select
将无法访问。解决这个问题的模式是什么?
package main
import (
"fmt"
"math/rand"
"time"
)
func myFunc() float64 {
c := make(chan float64)
for i := 0; i < 10; i++ {
go func() {
var value float64
value = someOp()
if value > .9 {
c <- value
}
}()
}
// unreachable code the if the for loop above is infinite
for {
select {
case x := <-c:
return x
default:
}
}
}
func someOp() float64 {
rand.Seed(time.Now().UnixNano())
return rand.Float64()
}
func main() {
fmt.Println(myFunc())
}
启动无限数量的 goroutines 通常不是一个好主意。更好的方法是启动固定数量的 goroutine,这些 goroutine 会循环寻找答案。 Return 从这些 goroutines 找到答案时。
func myFunc() float64 {
c := make(chan float64, 1) // Size 1 prevents race between main goroutine and workers
done := make(chan struct{})
defer close(done)
// Start a fixed number of goroutines
for i := 0; i < 10; i++ {
go func() {
for {
select {
case <-done:
// myfunc exited with result, return from this goroutine
return
default:
var value float64
value = someOp()
if value > .9 {
select {
case c <- value:
// This is first goroutine to send a value
default:
// Another goroutine sent a value
}
return
}
}
}
}()
}
return <-c
}