ZBLOG

package main import ( "fmt" "sync" ) func main() { chan1 := make(chan struct{}) chan2 := make(chan struct{}) chan3 := make(chan struct{}) var wg sync.WaitGroup wg.Add(3) var global int go func() { defer func() { wg.Done() chan2...

在你提供的Go程序中,global变量用于控制循环,并且当它达到10时,会停止所有的 goroutine。由于使用了多个通道(chan1, chan2, 和 chan3)来进行协作,运行逻辑如下:

  1. 初始化:程序开始时,通过发送一个信号到 chan1 开始第一个 goroutine。
  2. goroutine 逻辑
    • 第一个 goroutine 从 chan1 中读取,然后打印 “1”,接着检查 global 是否为10。如果不是,则发送信号到 chan2
    • 第二个 goroutine 从 chan2 中读取,然后打印 “2”,同样检查 global 是否为10。如果不是,则发送信号到 chan3
    • 第三个 goroutine 从 chan3 中读取,然后打印 “3”,增加 global 的值并再次检查是否为10,如果不是,就发送信号回到 chan1

为什么少打一个 “3”

问题出现在对全局变量的操作和通道的顺序上。在第三个 goroutine 打印 “3” 后,会将 global++ 之后才向通道发送信号。这意味着,当循环即将结束并且在执行最后一次迭代之前,它会因为某种竞争条件或顺序问题而错过最后一次打印。

具体来说,当:

  • 如果第二个 goroutine 在发出下一个信号前先检查了 global == 10
  • 或者如果在任何步骤中有相互阻塞的情况

在这些情况下,有可能导致“3”没有被打印出来,因为第三个 goroutine 到达了它的终止条件但没有机会再进行一次完整的循环来执行打印。

解决方案

为了确保每次迭代都能完成并且适当地增加计数,可以考虑对全局状态访问加锁,或者重新设计代码以消除这种竞争条件。例如,可以使用其他机制来确保当需要执行下一步时不会错过任何重要状态更新。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=20730

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?