繁体   English   中英

为什么 goroutine 通道会这样做?

[英]Why goroutine channel does this?

我是 golang 的新手。 我试图了解渠道是如何工作的,但这真的很令人困惑。

我评论了我的问题。 有人可以向我解释为什么这段代码会以这种奇怪的方式运行吗?

package main

import "fmt"

func main() {
    slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
    c := make(chan int)
    go pokeVals(slice, c)

    fmt.Println(slice)
    fmt.Println("start")
    <-c // why 2 "poke"s here?
    fmt.Println("-")
    <-c // why 0 "poke"s?
    //<-c // But if uncommented - 2 more "pokes" here

    fmt.Println("end")
}

func pokeVals(values []int, c chan int) {
    for _, val := range values {
        fmt.Println("poke")
        c <- val
    }
    fmt.Println("overpoked")
}

Golang 游乐场链接: https : //play.golang.org/p/u__cVyUbNJY

Goroutines 并发运行。 它们的调度方式不受您的控制,唯一的保证是您是否使用同步,例如通道、等待组或其他同步原语。

main()启动一个 goroutine,它在循环中发送c上的值。 但是在发送每个值之前,它首先打印"poke" 因此,即使您没有收到来自c您也可能会看到打印了一个"poke" 如果你确实从c接收到一个值,那么这个 goroutine 中的循环可以继续下一次迭代,再次打印"poke" ,它可能会立即打印,甚至在main() goroutine 开始打印"-" 这就是你所经历的。

原始版本中的main()协程(第 3 个<-c注释掉)终止(在打印"end" )。 一旦main()返回,您的应用程序就结束了,它不会等待其他 goroutines 完成。 这就是你所经历的。 有关详细信息,请参阅goroutine 无输出

如果您取消注释第三个<-c ,则main()必须在c上等待另一个发送,这意味着它肯定必须在此之前等待"poke"打印。 一旦pokeVals()的 goroutine 能够在c上发送另一个值,它可能会在下一次迭代的循环中再次打印"poke" (如果这被安排在从main()返回之前),这就是您所经历的。

您是否看到 2 个额外的"poke"打印是不确定的,其中 1 或 2 个都是有效结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM