【发布时间】:2020-07-30 22:19:34
【问题描述】:
使用 Golang 进行实验,我创建了一个带有 select 语句的函数,它监听两个通道。
我的问题是代码的行为似乎不确定 - 有时会出现恐慌,有时会成功完成。
我的期望是这段代码应该总是恐慌。它应该首先收到错误,因为它应该在 waitGroup 完成之前调度,因此在成功通道被推送到之前。
package main
import (
"errors"
"fmt"
"sync"
)
func main() {
errs := make(chan error, 1)
success := make(chan bool, 1)
doSomething(success, errs)
select {
case err := <-errs:
fmt.Println("error", err)
panic(err)
case <-success:
fmt.Println("success")
}
fmt.Println("finished successfully")
}
func doSomething(success chan bool, errs chan error) {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
err := errors.New("Some error")
errs <- err
}()
wg.Wait()
success <- true
}
【问题讨论】:
-
您正在频道之间开始竞速。 wg.Done 在您将错误发布到频道后立即调用。这解除了主 go 例程的阻塞。尝试在错误 之后添加 time.Sleep(100 * time.Millisecond)
标签: go