go - 如何确保所有 goroutines 没有 time.Sleep 终止?
问题描述
我正在尝试使用有关谁首先收到消息的例程进行试验。然而,当主 goroutine 终止时,一些 goroutine 仍然挂起。我通过panic
. 但是,如果我添加time.Sleep
它们都会终止。我猜这是因为,当主要的 go 例程结束时,Go 运行时找不到时间来终止其他例程。
package main
import (
"fmt"
"time"
)
func main() {
for i := 0; i < 1000000; i++ {
algo()
}
// without this, some goroutines do not terminate
// time.Sleep(time.Second)
panic("")
}
func algo() {
c := make(chan int)
wait := make(chan bool)
go racer(1, wait, c)
go racer(2, wait, c)
go racer(3, wait, c)
go racer(4, wait, c)
go racer(5, wait, c)
// who gets it first
c <- 5
close(wait)
}
func racer(name int, wait chan bool, c chan int) {
select {
case <-wait:
case v := <-c:
fmt.Println(name, ":", v)
}
}
解决方案
这正是sync.WaitGroup
它的用途。这是取自这篇博文的一个玩具示例:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
messages := make(chan int)
var wg sync.WaitGroup
// you can also add these one at
// a time if you need to
wg.Add(3)
go func() {
defer wg.Done()
time.Sleep(time.Second * 3)
messages <- 1
}()
go func() {
defer wg.Done()
time.Sleep(time.Second * 2)
messages <- 2
}()
go func() {
defer wg.Done()
time.Sleep(time.Second * 1)
messages <- 3
}()
go func() {
for i := range messages {
fmt.Println(i)
}
}()
wg.Wait()
}
推荐阅读
- python - 如何在 Airflow 中更新 AwsBatchOperator 任务代码?
- terraform - Terraform 忽略 AWS metric_query 中的子块更改
- .net - 如何使用 AWS Lamda 和 dotnet Core 5 将 Excel 上传到 Amazon S3?
- unreal-engine4 - 生成蓝图不会生成任何东西(UE4)
- azure - 如何在 Runbook 中使用运行方式帐户发送电子邮件
- php - 在单个查询中检索多级数据 - MySQL Group Concat
- ruby - `gets':无效的参数 -
红宝石中的 (Errno::EINVAL) - highcharts - xAxis 标签在 Highcharts 中不正确可见
- python - Whatsapp 日志解析 python
- python - img =detector.findHands(img) AttributeError: 'handDetector' 对象没有属性 'findHands'