解决了 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 <p>程序的预期行为是打印“显示第一条消息:hello”,然后退出。然而,实际输出包括 sum 函数的结果:</p> <pre class="brush:php;toolbar:false">display first message: hello 10000000000
解释
主 Goroutine 阻塞在该行上:
<code class="go"><p>这意味着主 Goroutine 在从通道 c 接收到值之前无法继续执行。 display 和 sum 都向 c 发送一个真值,这会解除主 goroutine 的阻塞。然而,调度器可以选择先运行哪个 goroutine。</p> <p>可能的执行顺序:</p> <ol> <li>Main 创建两个 goroutine 用于显示和求和。</li> <li>调度器运行 display首先,打印消息并在通道发送上阻塞。</li> <li>调度程序切换到 sum goroutine。</li> <li>Sum 计算并打印结果。</li> <li>调度程序恢复显示,向通道发送一个值。</li> <li>主协程收到值后退出。</li> </ol> <p><strong>解决方案</strong></p> <p>确保程序只打印第一个结果,我们可以使用结果通道:</p> <pre class="brush:php;toolbar:false"><code class="go">func display(msg string, result chan string) { result <p>并将main函数更改为:</p> <pre class="brush:php;toolbar:false"><code class="go">func main() { result := make(chan string) go display("hello", result) fmt.Println(</code>
以上是Go 并发:为什么我的程序在使用通道时打印出意外的输出?的详细内容。更多信息请关注PHP中文网其他相关文章!