go - 无限的 goroutines,直到收到所需的响应
问题描述
我正在尝试在无限循环中启动 goroutine,直到我得到我正在寻找的响应,但是select
如果我更改for i := 0; i < 10; i++ {}
为for {}
. 解决这个问题的模式是什么?
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())
}
解决方案
启动无限数量的 goroutine 通常不是一个好主意。更好的方法是启动固定数量的 goroutine 循环寻找答案。找到答案后从这些 goroutine 中返回。
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
}
推荐阅读
- amazon-web-services - 如何从另一个 Lambda 传递 Lambda 调用中的标头
- flutter - Dart如何按字符串过滤数组
- javascript - 错误 [ERR_HTTP_HEADERS_SENT]:尝试对 Next.js 应用程序进行身份验证时,无法在将标头发送到客户端后设置标头
- sql - 在 PostgreSQL 中获取 current_timestamp 的一部分
- codeblocks - MinGW 文件夹代码块中没有 GL 文件夹用于 glut
- c# - 使用 c# 创建一个谷歌日历事件,询问用户的开始和结束
- mongodb - 如何为 init-mongo.sh:ro 编写 bash 脚本以添加管理员用户并运行初始化脚本
- javascript - 使用与原始文件相同的uglyfyjs 3 输出文件
- java - 读取Tomcat目录外的文件
- azure - 如何安排将 azure sql 托管实例数据库每日备份到 azure blob