gpt4 book ai didi

Go channel 未接收/打印发送到 channel 的最后一个值

转载 作者:数据小太阳 更新时间:2023-10-29 03:08:13 25 4
gpt4 key购买 nike

这是一段代码,它输出推送到 channel 的整数列表。否则选择检查并打印必要的超时消息。

package main

import (
"fmt"
"sync"
"time"
)

var wg sync.WaitGroup

func 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())
}
}
}()

}

这里还有相同的 playground 链接:https://play.golang.org/p/4hNWze4Pfwr此代码输出整数列表,如

Read 10
Read 20
Read 30
Read 40
Read 50

但是当我取消注释使主例程进入休眠 5 秒的行时(在代码中提到为注释/行号 16),输出更改为:

TIMED OUT with 2009-11-10 23:00:02 +0000 UTC m=+2.000000001
Read 10
Read 20
Read 30
Read 40

我想了解为什么最后一个 Read 50 没有在第二种情况下打印出来。

最佳答案

问题是您的 wg.Done() 放错了地方。它必须在您的 goroutine 中,但您甚至在 goroutine 启动之前就执行了它,因此您的程序可能会在执行任何工作之前退出。

改变这个:

defer wg.Done()
go func() {

为此:

go func() {
defer wg.Done()

当然,您将拥有一个无限运行的 goroutine,因为您的 for 循环没有退出条件。您需要添加一个,可能是通过检查 channel 是否关闭:

        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 例程在完成后关闭 channel :

c <- 40
c <- 50
close(c) // We're done, so tell the goroutine to finish up
wg.Wait() // But wait until it's done

关于Go channel 未接收/打印发送到 channel 的最后一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57443099/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com