解决了 Go 并发和通道混乱
在 Go 中处理并发时,通道在 goroutine 之间的通信中发挥着关键作用。然而,它们的行为有时会导致混乱。
考虑以下 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>
程序的预期行为是打印“显示第一条消息:hello”,然后退出。然而,实际输出包括 sum 函数的结果:
display first message: hello 10000000000
解释
主 Goroutine 阻塞在该行上:
<code class="go"><-c</code>
这意味着主 Goroutine 在从通道 c 接收到值之前无法继续执行。 display 和 sum 都向 c 发送一个真值,这会解除主 goroutine 的阻塞。然而,调度器可以选择先运行哪个 goroutine。
可能的执行顺序:
解决方案
确保程序只打印第一个结果,我们可以使用结果通道:
<code class="go">func display(msg string, result chan string) { result <- msg }</code>
并将main函数更改为:
<code class="go">func main() { result := make(chan string) go display("hello", result) fmt.Println(<-result) }</code>
以上是Go 并发:为什么我的程序在使用通道时打印出意外的输出?的详细内容。更多信息请关注PHP中文网其他相关文章!