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

原文地址:https://www.cnblogs.com/williamjie/p/10053298.html

时间: 2024-08-06 13:56:14

golang中map并发读写问题及解决方法的相关文章

golang map并发读写异常导致服务崩溃

昨天突然接到报警说服务端口丢失,也就是服务崩溃了. 1, 先看错误日志,发现是调用json.Marshal时出错了,错误原因是:concurrent map iteration and map write,即并发读写map. fatal error: concurrent map iteration and map write goroutine 543965 [running]: runtime.throw(0xb74baf, 0x26) /usr/local/go1.10.1/src/run

编程中遇到的Python错误和解决方法汇总整理

这篇文章主要介绍了自己编程中遇到的Python错误和解决方法汇总整理,本文收集整理了较多的案例,需要的朋友可以参考下 开个贴,用于记录平时经常碰到的Python的错误同时对导致错误的原因进行分析,并持续更新,方便以后查询,学习.知识在于积累嘛!微笑+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++错误: 复制代码代码如下: >>> def f(x, y):      print x, y  >>> t

java新手在实际开发中所遇到的问题及解决方法小结,(持续更新遇到的问题)

?从事开发一年有余,想到自己初入公司时的困窘,在此把我记忆中在实际开发中所遇到的问题做一总结性的小结,为自己以后方便查阅,以及后来者遇到相同问题时解决更加方便快捷,希望大家集思广益把自己遇到的问题及解决方法写出来,添砖加瓦.为后来者给予一点帮助! 实用案例 如何使用Java实现汉诺塔问题 Java中定时器的使用方法 Java打印杨辉三角的具体实现代码 Java中如何实现分页功能 Java读取大文件如何高效率 Java中生成随机数的几种方法 Java zip压缩单个文件实现方法 如何计算Java对

【LaTex】Texstudio中中文文本乱码问题的解决方法

Texstudio中中文文本乱码问题的解决方法:1.因为默认编码是UTF8,ctex的编码是GBK,所以出现乱码.将texstudio编码设成GBK乱码自然消失.2.通过拷贝粘贴,不会出现乱码.3.texstudio构建的编译平台是pdflatex,GBK编码时无需加UTF8选项,加了反而慢,甚至出错.不知为什么?4.编码是UTF8时,宜用xelatex编译,很快.5.Sublimetext可将GBK编码转存为UTF8,转存后用texstudio打开不会出现乱码.如果出现将默认编码改成UTF8就

Windows中openProcess函数返回ERROR_ACCESS_DENIED的解决方法

辛辛苦苦开始了创业,好不容易见到了天使投资人,如何去打动明星投资人?如何能拿到那一笔"救命"钱?看徐小平.雷军这样说. 1. 天使投资人偏爱投什么样的创业者? 雷军:你有强烈的渴望做成一件伟大的事情,并且能让投资者相信你能做得成这件事情.掏自己的钱创业是创业成功率最高的一种,因为在那一瞬间你重视了,你花的每一分钱都是自己的血汗钱和别人的血汗钱,不会轻松把别的投资人的钱打水漂. 曾李青:我们体系内投了好几家公司,发现我们投资成功的公司要么是有做大公司的成功经验,要么是名校毕业.好学校不一

(转) SQL Server中 ldf 文件过大的解决方法

原文地址:http://blog.itpub.net/35489/viewspace-616459/ 在SQL Server中经常遇到事务日志变大的情况,除了将数据库设置为“自动收缩”外,还可以使用下面的SQL命令进行快速清除数据库中的事务日志,命令如下:  - 第一步:清空日志  DUMP TRANSACTION   databasename   WITH   NO_LOG  -- 第二步:截断事务日志  BACKUP LOG   databasename   WITH   NO_LOG  -

C语言中常见的内存错误与解决方法

常见的错误 关于内存的一些知识已在内存分配中提及,现记录与分享常见的内存错误与对策. 类型 1:内存未分配成功,却使用了它. 方   法:在使用之前检查指针是否为NULL. 1)当指针p是函数的参数时,在函数入口处用语句assert(p!=NULL)进行断言检查. 2)当使用malloc或new来申请内存时,应该用if(p != NULL)进行防错检查. 类型 2:引用了尚未初始化的指针 原   因:内存的缺省初始值究竟是什么并没有统一的标准,在使用之前都进行初始化. 1)没有初始化的观念. 2

node开发指南中的microblog项目中遇到的问题总结及解决方法

1      使用connect-mongdo时,报错:Cannot read property 'Store' of undefined 解决: require('connect-mongo')的时候加一个参数express,如下: var express = require('express'); var MongoStore = require('connect-mongo')(express), 2      使用app.use(express.router(routers)) 提示 h

bash脚本中出现[[:not found错误的解决方法

bash脚本中出现[[:not found错误的解决方法--bash脚本总结1 今天在写脚本的时候,发生了一个奇怪的问题:在脚本中使用[[的时候报错“[[: not found”.遇到问题自然是解决问题. 1. 使用的bash版本太低? bash --version查看bash版本信息如下 [email protected]:~$bash --version GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu) Copyright (C)