zoukankan      html  css  js  c++  java
  • golang竞态条件数据一致性|map安全

    我们在写业务代码中,有一种情景比较常见。

        目标一个list(数组),我们想要遍历去发起一些请求,或者远程动作,但参数不同。实际场景如,给一批用户发短信,短信内容一样,但是uid不同,需要遍历构造参数。

        用golang,我们能很方便的for循环,使用协程来并发处理。直观能想到的执行代码如下:

    但是上面代码执行会出现什么问题呢?我们看下结果

    惊奇的发现,最终的参数aaa 都是5,并没有达到想要的 0,1,2,3,4

    怎么解决呢?直观想到传入参数i到协程中

    结果,不全是5了,但是无序的,也没有达到想要的0,1,2,3,4,而是0,1,4,3,3!

     

    到这里,可能想到,map无序且不安全,共用一块地址,早被协程写的乱飞了。

    终极办法,加锁

    当然,到这里还没完全安全,且看aaa=bb 这段代码,在for数据量足够多的情况,是会报共写一块map地址错误的painc

    这样,就安全多了。贴下最终代码

    var bb = map[string]int{
       "bb": 1,
    }
    wg := sync.WaitGroup{}
    var lock sync.Mutex
    for i := 0; i < 5; i++ {
       wg.Add(1)
       go func(w *sync.WaitGroup, i int) {
          lock.Lock()
          fmt.Println(i)
          aaa := make(map[string]int, 10)
          aaa["bb"] = bb["bb"]
          aaa["aaa"] = i
          fmt.Println(aaa)
          fmt.Println(i)
          lock.Unlock()
          w.Done()
       }(&wg, i)
    }
    wg.Wait()
  • 相关阅读:
    CSUFT 1002 Robot Navigation
    CSUFT 1003 All Your Base
    Uva 1599 最佳路径
    Uva 10129 单词
    欧拉回路
    Uva 10305 给任务排序
    uva 816 Abbott的复仇
    Uva 1103 古代象形文字
    Uva 10118 免费糖果
    Uva 725 除法
  • 原文地址:https://www.cnblogs.com/already/p/15683869.html
Copyright © 2011-2022 走看看