zoukankan      html  css  js  c++  java
  • golang中map并发读写问题及解决方法

     
    这是一个创建于 2017-03-05 06:02:54 的文章,其中的信息可能已经有所发展或是发生改变。

    一、map并发读写问题

    如果map由多协程同时读和写就会出现 fatal error:concurrent map read and map write的错误

    如下代码很容易就出现map并发读写问题

    func main(){

    c := make(map[string]int)
           go func() {//开一个协程写map
                for j := 0; j < 1000000; j++ {
                  c[fmt.Sprintf("%d", j)] = j
                }
           }()
           go func() {    //开一个协程读map
                 for j := 0; j < 1000000; j++ {
                     fmt.Println(c[fmt.Sprintf("%d",j)])
                 }
           }()

     time.Sleep(time.Second*20)

    }
     

    多个协程同时写也会出现fatal error: concurrent map writes的错误

    如下代码很容易出现map并发写的问题

    func main(){

    c := make(map[string]int)

    for i := 0; i < 100; i++ {
            go func() {  //开100个协程并发写map
                  for j := 0; j < 1000000; j++ {
                         c[fmt.Sprintf("%d", j)] = j
                  }
            }()
            }
           time.Sleep(time.Second*20)  //让执行main函数的主协成等待20s,不然不会执行上面的并发操作

    }

    二、出现问题的原因

    因为map为引用类型,所以即使函数传值调用,参数副本依然指向映射m, 所以多个goroutine并发写同一个映射m, 写过多线程程序的同学都知道,对于共享变量,资源,并发读写会产生竞争的, 故共享资源遭到破坏

    三、解决方法

    1、加锁

    (1)通用锁

    type Demo struct {

      Data map[string]string 

      Lock sync.Mutex

    }

    func (d Demo) Get(k string) string{

      d.Lock.Lock()

      defer d.Lock.UnLock()

      return d.Data[k]

    }

    func (d Demo) Set(k,v string) {

      d.Lock.Lock()

      defer d.Lock.UnLock()

      d.Data[k]=v

    }

    (2)读写锁

    type Demo struct {

      Data map[string]string 

      Lock sync.RwMutex

    }

    func (d Demo) Get(k string) string{

      d.Lock.RLock()

      defer d.Lock.RUnlock()

      return d.Data[k]

    }

    func (d Demo) Set(k,v string) {

      d.Lock.Lock()

      defer d.Lock.UnLock()

      d.Data[k]=v

    }

    2、利用channel串行化处理

     
  • 相关阅读:
    html5--html实现乘法口诀表
    html5--switch选择结构的优化
    CSS盒子模型
    html5--项目实战-仿天猫(移动端页面)
    关于运动
    自然拼读法长元音
    揭开自然拼读法(Phonics)的神秘面纱
    ExtJs自学教程(1):一切从API開始
    四个好看的CSS样式表格
    【Linux】linux经常使用基本命令
  • 原文地址:https://www.cnblogs.com/williamjie/p/9933644.html
Copyright © 2011-2022 走看看