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

  • 相关阅读:
    (转)Entity Framework 4.1 之三(由4.0过渡到4.1/4.3)
    (转)修改的T4代码生成器(续)
    (转)【Smart Code Generator】 基于T4的代码生成器
    linux下播放mp3
    poj 2777 Count Color
    poj 1062 昂贵的聘礼
    uva 991 Safe Salutations
    uva 10587 Mayor's posters
    poj 2528 Mayor's posters
    逆序数
  • 原文地址:https://www.cnblogs.com/mafeng/p/9018110.html
Copyright © 2011-2022 走看看