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

     
  • 相关阅读:
    flash使用lua
    如何写出兼容大部分浏览器的CSS 代码
    typeof 详解
    人月神话阅读笔记(三)
    人月神话阅读笔记(二)
    仓库物资管理
    动手动脑(四)
    人月神话阅读笔记(一)
    动手动脑(六 文件操作)及课后作业
    java异常处理
  • 原文地址:https://www.cnblogs.com/williamjie/p/9933644.html
Copyright © 2011-2022 走看看