简体   繁体   English

为什么 goroutine 通道会这样做?

[英]Why goroutine channel does this?

I'm new with golang.我是 golang 的新手。 I'm trying to understand how channels work, but it's really confusing.我试图了解渠道是如何工作的,但这真的很令人困惑。

I commented my questions.我评论了我的问题。 Can someone explain to me why this code behaves in this strange way?有人可以向我解释为什么这段代码会以这种奇怪的方式运行吗?

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 playground link: https://play.golang.org/p/u__cVyUbNJY Golang 游乐场链接: https : //play.golang.org/p/u__cVyUbNJY

Goroutines run concurrently. Goroutines 并发运行。 How they're scheduled is out of your hands, the only guarantee you get regarding to that is if you use synchronization such as channels, waitgroups or other synchronization primitives.它们的调度方式不受您的控制,唯一的保证是您是否使用同步,例如通道、等待组或其他同步原语。

From main() you launch a goroutine which sends values on c in a loop.main()启动一个 goroutine,它在循环中发送c上的值。 But before sending each value, it first prints "poke" .但是在发送每个值之前,它首先打印"poke" So you may see one "poke" printed even if you don't receive from c .因此,即使您没有收到来自c您也可能会看到打印了一个"poke" If you do receive a value from c , then the loop in this goroutine can proceed to the next iteration which again prints "poke" , and it may do so immediately, even before the main() goroutine gets to printing "-" .如果你确实从c接收到一个值,那么这个 goroutine 中的循环可以继续下一次迭代,再次打印"poke" ,它可能会立即打印,甚至在main() goroutine 开始打印"-" This is what you experience.这就是你所经历的。

The main() goroutine in the original version (3rd <-c commented out) terminates (after printing "end" ).原始版本中的main()协程(第 3 个<-c注释掉)终止(在打印"end" )。 Once main() returns, your app ends, it does not wait for other goroutines to finish.一旦main()返回,您的应用程序就结束了,它不会等待其他 goroutines 完成。 This is what you experience.这就是你所经历的。 For details, see No output from goroutine .有关详细信息,请参阅goroutine 无输出

If you uncomment the 3rd <-c , then main() must wait another send on c , which means it definitely has to wait for the "poke" print before that.如果您取消注释第三个<-c ,则main()必须在c上等待另一个发送,这意味着它肯定必须在此之前等待"poke"打印。 And once pokeVals() 's goroutine is able to send another value on c , it may print "poke" again in the loops next iteration (if this is scheduled earlier than returning from main() ), which is what you experience.一旦pokeVals()的 goroutine 能够在c上发送另一个值,它可能会在下一次迭代的循环中再次打印"poke" (如果这被安排在从main()返回之前),这就是您所经历的。

Whether you see 2 additional "poke" 's printed is not deterministic, 1 or 2 of them are both valid results.您是否看到 2 个额外的"poke"打印是不确定的,其中 1 或 2 个都是有效结果。

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

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