这是一段代码,它输出推送到通道的整数列表。否则,选择检查并打印必要的超时消息。package mainimport ( "fmt" "sync" "time")var wg sync.WaitGroupfunc main() { wg.Add(1) c := make(chan int) go readFromChannel(c, time.After(time.Duration(2)*time.Second))// time.Sleep(time.Duration(5) * time.Second) //Talking about uncommenting this line c <- 10 c <- 20 c <- 30 c <- 40 c <- 50 wg.Wait()}func readFromChannel(c chan int, ti <-chan time.Time) { defer wg.Done() go func() { for { select { case x := <-c: fmt.Println("Read", x) case t :=<-ti: fmt.Println("TIMED OUT with "+t.String()) } } }()}另外,这里还有相同的游乐场链接: https: //play.golang.org/p/4hNWze4Pfwr 此代码输出整数列表,例如Read 10Read 20Read 30Read 40Read 50但是,当我取消注释使主例程进入睡眠状态 5 秒的行(在代码中称为注释/行号 16)时,输出更改为:TIMED OUT with 2009-11-10 23:00:02 +0000 UTC m=+2.000000001Read 10Read 20Read 30Read 40我想了解为什么Read 50在第二种情况下没有打印最后一个。
1 回答
大话西游666
TA贡献1817条经验 获得超14个赞
问题是你的wg.Done()位置不对。它必须在你的 goroutine 中,但是你在 goroutine 启动之前执行它,所以你的程序很可能在做任何工作之前退出。
改变这个:
defer wg.Done()
go func() {
对此:
go func() {
defer wg.Done()
当然,你将拥有一个无限运行的 goroutine,因为你的for循环没有退出条件。您需要添加一个,可能是通过检查通道关闭来添加:
select {
case x, ok := <-c:
if !ok { // channel was closed
return
}
fmt.Println("Read", x)
case t :=<-ti:
fmt.Println("TIMED OUT with "+t.String())
}
然后告诉你的主 go 例程在完成后关闭通道:
c <- 40
c <- 50
close(c) // We're done, so tell the goroutine to finish up
wg.Wait() // But wait until it's done
- 1 回答
- 0 关注
- 89 浏览
添加回答
举报
0/150
提交
取消