golang在多个go routine中进行map或者slice操作应该注意的对象。

因为golang的map和列表切片都是引用类型,且非线程安全的,所以在多个go routine中进行读写操作的时候,会产生“map read and map write“的panic错误。

某一些类型的对象,会有这种类似的set方法来写数据,或者get方法来返回一个map:

func (this *object) Set(name, val) {
  this.Lock()
  defer this.Unlock()
  
  this.m[name] = val
}

func (this *object) Get() map[string]string {
  this.Lock()
  defer this.Unlock()

  return this.m
}

  

如果会在多个go routine中通过该对象的Get()方法获取到的map进行读操作,并且在其他go routine中用Set()方法来写操作,那么有可能会导致“map read and map write“的panic错误。

原因是Get方法获取的map和Set方法操作的map是同一个map,如果读写线程在同一时刻操作这2个map,就会产生错误。

所以Get方法最好用这种方式返回map:

func (this *object) Get() map[string]string {
    this.Lock()
    defer this.Unlock()

    newm := make(map[string]string)
    for k, v := range this.m {
        newm[k] = v
    }

    return newm
}

这样每次Get获取的map,其实是一个新的map,就可以不用考虑同时读写的问题了。

原文地址:https://www.cnblogs.com/yzhch/p/8137128.html

时间: 2024-09-30 07:03:25

golang在多个go routine中进行map或者slice操作应该注意的对象。的相关文章

javascript中的map和reduce

今天在看"廖雪峰官方网站"的js教程时,看到了map和reduce.其中有一个练习题是:不使用js内置的parseInt()函数,利用map和reduce操作实现一个string2int()函数(先将字符串转换为数组,再将数组转换为从arr[0]到arr[arr.(length-1)]的一个数字.比如:把[1, 3, 5, 7, 9]变换成整数13579. 我的解法: function toNum(str) { var arr=[]; for(var i=0;i<str.leng

Delphi接口的底层实现(接口在内存中仍然有其布局,它依附在对象的内存空间中,有汇编解释)——接口的内存结构图,简单清楚,深刻 good

引言 接口是面向对象程序语言中一个很重要的元素,它被描述为一组服务的集合,对于客户端来说,我们关心的只是提供的服务,而不必关心服务是如何实现的:对于服务端的类来说,如果它想实现某种服务,实现与该服务相关的接口即可,它也不必与使用服务的客户端进行过多的交互.这种良好的设计方式已经受到很广泛的应用. 早在Delphi 3的时候就引入了接口的概念,当时完全是因为COM的出现而诞生的,但经过这么多版本的进化,Delphi的接口已经成为Object Pascal语言的一部分,我们完全可以用接口来完成我们的

沙盒模型中各文件夹及操作

某个iphone工程进行文件操作有此工程对应的指定的位置,不能逾越. iphone沙箱模型的有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么. documents,tmp,app,Library. (NSHomeDirectory()), 手动保存的文件在documents文件里 Nsuserdefaults保存的文件在tmp文件夹里 Documents 目录:您应该将所有de应用程序数据文件写入到这个目录下.这个目录用于存储用户数据或其它应该定期备份的信

C语言中关于对目录的操作

原文地址:C语言中关于对目录的操作 目录的操作不论是在嵌入式产品还是应用软件编程都是必不可少的,不同的开发语言可能略有不同,笔者主要是讨论在Linux平台下对目录的一系列操作: 1.获取当前目录操作: 在系统命令行下我们可以直接输入命令:pwd 来获取当前的工作目录,但是你知道这个命令是怎么执行的吗?它是由系统通过 Shell 程序来解释执行的,在我们自己编写程序的时候怎么能获取当前的工作目录呢?在标准C库中提供了一系列关于目录操作的接口函数: char * getcwd(char * buf,

深度分析如何在Hadoop中控制Map的数量

深度分析如何在Hadoop中控制Map的数量 [email protected] 很多文档中描述,Mapper的数量在默认情况下不可直接控制干预,因为Mapper的数量由输入的大小和个数决定.在默认情况下,最终input 占据了多少block,就应该启动多少个Mapper.如果输入的文件数量巨大,但是每个文件的size都小于HDFS的blockSize,那么会造成 启动的Mapper等于文件的数量(即每个文件都占据了一个block),那么很可能造成启动的Mapper数量超出限制而导致崩溃.这些逻

java中遍历MAP的几种方法

java中遍历MAP的几种方法 Java代码 Map<String,String> map=new HashMap<String,String>();    map.put("username", "qq");    map.put("passWord", "123");    map.put("userID", "1");    map.put("em

Java中有关剪切板的操作

Java提供两种类型的剪贴板:系统的和本地的. 本地剪贴板只在当前虚拟机中有效.Java允许多个本地剪贴板同时存在,可以方便地通过剪贴板的名称来进行存取访问. 系统剪贴板与同等操作系统直接关连,允许应用程序与运行在该操作系统下的其它程序之间进行信息交换. 在进一步深入之前,先看看与剪贴板相同的java类,这些类主要包含在java.awt.datatransfer包中,主要有以下几种: Clipboard类: 此类实现一种使用剪切/复制/粘贴操作传输数据的机制. ClipboardOwner接口:

Struts2中获取Web元素request、session、application对象的四种方式

我们在学习web编程的时候,一般都是通过requet.session.application(servletcontext)进行一系列相关的操作,request.session.和application他们都是web开发最常用和最实用的对象,有了它们可以大大方便开发人员进行开发和操作.但是在struts2中,基本都是action,这些个方法都是没有requet.session.application,所以如何获取这几个常用对象,也成了大家都比较关注的问题,下面我就来演示下,如何在struts2中

hive优化之------控制hive任务中的map数和reduce数

.    控制hive任务中的map数:  1.    通常情况下,作业会通过input的目录产生一个或者多个map任务. 主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为128M, 可在hive中通过set dfs.block.size;命令查看到,该参数不能自定义修改): 2.    举例: a)    假设input目录下有1个文件a,大小为780M,那么Hadoop会将该文件a分隔成7个块(6个128m的块和1个12m的块),从而产生7个ma