为了账号安全,请及时绑定邮箱和手机立即绑定

需要一点帮助来理解代码流程?我不明白输出中的routine-end 是如何出现在其他输出语句之间的

需要一点帮助来理解代码流程?我不明白输出中的routine-end 是如何出现在其他输出语句之间的

Go
UYOU 2022-05-23 17:13:12
试图理解 goroutine 的流程,所以我写了这段代码,只有一件我无法理解的事情是,routine-end 如何在其他 go 例程之间运行并完成单个 go 例程并在最后打印来自通道的输出.import(    "fmt")func add(dataArr []int,dataChannel chan int,i int ){    var sum int    fmt.Println("GOROUTINE",i+1)    for i:=0;i<len(dataArr);i++{        sum += dataArr[i]    }    fmt.Println("wRITING TO CHANNEL.....")    dataChannel <- sum    fmt.Println("routine-end")}func main(){    fmt.Println("main() started")    dataChannel := make(chan int)    dataArr := []int{1,2,3,4,5,6,7,8,9}    for i:=0;i<len(dataArr);i+=3{        go add(dataArr[i:i+3],dataChannel,i)    }       fmt.Println("came to blocking statement ..........")    fmt.Println(<-dataChannel)    fmt.Println("main() end")}outputmain() startedcame to blocking statement ..........GOROUTINE 1wRITING TO CHANNEL.....routine-endGOROUTINE 4wRITING TO CHANNEL.....6main() end
查看完整描述

1 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

您的循环启动了 3 个调用该函数for的 goroutine 。add

此外,main它本身在一个单独的“主”goroutine 中运行。

由于 goroutines 并发执行,它们的运行顺序通常是不可预测的,并且取决于时间、机器的繁忙程度等。运行之间和机器之间的结果可能会有所不同。在不同的地方插入time.Sleep呼叫可能有助于将其可视化。例如,time.Sleep在“来到阻塞语句”之前插入 100ms 表明所有addgoroutines 启动。

您在运行中通常会看到一个addgoroutine 启动,将其切片添加到其上并sum写入. 由于启动了一些 goroutine 并立即从通道中读取,因此该读取获取了写入的内容,然后程序就存在了——因为默认情况下 main 不会等待所有 goroutine 完成sumdataChannelmainsumadd

此外,由于dataChannel通道是无缓冲的并且main只读取一个值,因此其他addgoroutine 将在写入时无限期地阻塞在通道上。


查看完整回答
反对 回复 2022-05-23
  • 1 回答
  • 0 关注
  • 111 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信