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

    一、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串行化处理

  • 相关阅读:
    讨论: 在WebControl中的Button,同时有onClientClick和onclick事件,验证控件实效
    在DropDownList中显示树形结构
    我的软件开场白+简单的通讯录
    DataList中动态添加控件遇到的问题
    伤心啊!不知道怎么感冒了
    存储过程实现无限级分类(2)
    上传文件类
    一个用泛型,和Sql语句分页的源代码
    在GridView中用Js实现全选
    [转]如何完美应对面试
  • 原文地址:https://www.cnblogs.com/mafeng/p/9018110.html
Copyright © 2011-2022 走看看