白首方悔读书迟 2022-04-19 11:35 采纳率: 100%
浏览 58
已结题

go 匿名函数协程中直接修改上级切片的安全性

问题遇到的现象和发生背景

我想确认一下下列代码是否会有问题

问题相关代码,请勿粘贴截图
type bb struct {
    a int
    b string
}
func a1() {
    aa :=[]bb{{a: 0,b: "b0",},{a:1,b:"b1"},{a:2,b:"b2"},{a:3,b:"b3"},{a:4,b:"b4"}}
    for i := 0; i < 5; i++ {
        go func(wz int) {
            aa[wz].b="完毕"+strconv.Itoa(wz)
        }(i)
    }
time.Sleep(time.Millisecond*5000)
    fmt.Printf("最终结果%+v",aa)
}

运行结果及报错内容

最终结果符合预期

我的解答思路和尝试过的方法

目前看来结果达到我的预期

我想要达到的结果

因为项目中我不想用chan来通讯所以想用上述带的思路.
我想知道在实际项目中这样用是否会有问题,实际中bb struct结构体比较复杂

  • 写回答

5条回答 默认 最新

  • ohko 2022-04-24 19:23
    关注

    从代码逻辑来看,没毛病,并且结果也是与你的预期一致的:

    1. 由于这里是用的传值匿名函数,go func(wz int)(i),所有没有多协程问题。
    2. 后面的sleep 5秒很关键,但是如果等待的时间不够,上面的协程执行的内容如果比较复杂时,耗时比较多的话,结果可能就会和预期的不同。
    3. 如果aa切片数据比较多时,就会启动非常多的协程。

    最好是将sleep 5秒改进一下,用一个Group锁会好得多。

    func a1() {
        var wg sync.WaitGroup // 添加定义
        aa := []bb{{a: 0, b: "b0"}, {a: 1, b: "b1"}, {a: 2, b: "b2"}, {a: 3, b: "b3"}, {a: 4, b: "b4"}}
    
        wg.Add(len(aa)) // 添加计数
        for i := 0; i < 5; i++ {
            go func(wz int) {
                aa[wz].b = "完毕" + strconv.Itoa(wz)
                wg.Done() // 完成一个计数
            }(i)
        }
    
        wg.Wait() // time.Sleep(time.Millisecond * 5000)
        fmt.Printf("最终结果%+v", aa)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

问题事件

  • 系统已结题 5月4日
  • 已采纳回答 4月26日
  • 创建了问题 4月19日

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)