猿问

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

试图理解 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")


}

output


main() started

came to blocking statement ..........

GOROUTINE 1

wRITING TO CHANNEL.....

routine-end

GOROUTINE 4

wRITING TO CHANNEL.....

6

main() end


UYOU
浏览 112回答 1
1回答

胡说叔叔

您的循环启动了 3 个调用该函数for的 goroutine 。add此外,main它本身在一个单独的“主”goroutine 中运行。由于 goroutines 并发执行,它们的运行顺序通常是不可预测的,并且取决于时间、机器的繁忙程度等。运行之间和机器之间的结果可能会有所不同。在不同的地方插入time.Sleep呼叫可能有助于将其可视化。例如,time.Sleep在“来到阻塞语句”之前插入 100ms 表明所有addgoroutines 启动。您在运行中通常会看到一个addgoroutine 启动,将其切片添加到其上并sum写入.&nbsp;由于启动了一些 goroutine 并立即从通道中读取,因此该读取获取了写入的内容,然后程序就存在了——因为默认情况下 main 不会等待所有 goroutine 完成。sumdataChannelmainsumadd此外,由于dataChannel通道是无缓冲的并且main只读取一个值,因此其他addgoroutine 将在写入时无限期地阻塞在通道上。
随时随地看视频慕课网APP

相关分类

Go
我要回答