Go 并发和通道混乱
问题
用户正在尝试理解 Go 并发和通道使用以下代码片段:
<code class="go">package main import "fmt" func display(msg string, c chan bool) { fmt.Println("display first message:", msg) c <- true } func sum(c chan bool) { sum := 0 for i := 0; i < 10000000000; i++ { sum++ } fmt.Println(sum) c <- true } func main() { c := make(chan bool) go display("hello", c) go sum(c) <-c }</code>
预期输出仅为“显示第一条消息:你好”,因为主函数一旦从通道接收到数据就应该退出。然而,实际输出还包括 100 亿个数字的总和。
答案
代码中的主要问题是调度器可以在两个 goroutine 之间自由选择(显示和求和)未被阻止。虽然程序员期望显示首先完成并在求和完成之前将数据发送到通道,但由于调度程序的不确定性,这种情况可能不会发生。
在一种可能的执行场景中:
为了解决这个问题并确保只打印“display first message: hello”消息,一种方法是使用结果通道接收来自 display 的消息并立即终止程序。修改后的 main 函数为:
<code class="go">func main() { result := make(chan string) go display("hello", result) fmt.Println(<-result) }</code>
以上是为什么我的 Go 代码打印 100 亿个数字的总和,而不是仅仅'显示第一条消息:你好”?的详细内容。更多信息请关注PHP中文网其他相关文章!