go - 为什么使用goroutine channel ?

标签 go channel goroutine

我是golang的新手。我试图了解 channel 的运作方式,但这确实令人困惑。

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

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同时运行。如何安排它们是您无法控制的,因此,唯一的保证就是如果您使用同步,例如 channel , WaitGroup 或其他同步原语。

main()中启动一个goroutine,该例程在循环中发送c上的值。但是在发送每个值之前,它首先打印"poke"。因此,即使您没有收到"poke",您也可能会看到一个c打印。如果您确实从c接收到一个值,则此goroutine中的循环可以继续进行下一次迭代,该迭代再次打印"poke",并且即使在main() goroutine可以打印"-"之前,它也可能立即执行。这就是您的经验。

原始版本中的main() goroutine(已注释掉第三个<-c)终止(在打印"end"之后)。 main()返回后,您的应用程序结束,它不会等待其他goroutine完成。这就是您的经验。有关详细信息,请参见No output from goroutine

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

是否看到另外2个"poke"的输出是不确定的,其中1或2个都是有效结果。

关于go - 为什么使用goroutine channel ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60127124/

相关文章:

go - 如何在最新的 Go 周报中比较两个函数的指针相等性?

docker - 如何在Docker Compose多容器应用程序中使用GoCQL连接到bitnami/cassandra?

string - 读取一个文本文件,替换其中的单词,输出到另一个文本文件

concurrency - 从不同的 goroutine 访问一个 channel

go - Goroutines节气门示例

concurrency - Go 中互斥锁的问题

go - 如何从其他函数解析 slice

javascript - 按名称将 channel 添加到类别

java - RabbitMQ和channel和connection的关系

go - golang channel 收不到