前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Golang map 并发读写问题源码分析

Golang map 并发读写问题源码分析

原创
作者头像
Lynalmost
发布于 2022-06-27 09:13:22
发布于 2022-06-27 09:13:22
1.5K0
举报

map介绍及问题描述

map主要用来存储kv数据,其底层使用的是开链法去冲突的hashtable,拥有自动扩容机制。使用map最方便的一点是可以O(1)快速查询(目前slice并没有提供查询接口,只能通过自己写算法实现某个元素是否存在)。

map虽然好用,但是可能不适用。

但是map有一个非常致命的坑点,在并发场景下,并发读/写都可能会出现fatal error:concurrent map read and map write的错误,刚开始使用map的时候天真的认为只要不对同一个key进行并发操作就行,但是现实很骨感。测试时并发量很小的时候可能不会存在问题(只是运气好),并发量一大就会有问题。

但是不是所有场景下并发使用map都是不安全的

这是golang的官方文档,上面提到了只要有更新的操作存在,map就是非线程安全的,但是如果使用场景只是并发读,不涉及到写/删操作,那么就是并发安全的。

image.png
image.png

源码分析

定义

map head中flags字段,记录了当前map的一些状态,其中hashWriting就是造成并发读写map报错的“罪魁祸首”。

代码语言:txt
AI代码解释
复制
// A header for a Go map.
type hmap struct {
	// Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go.
	// Make sure this stays in sync with the compiler's definition.
	count     int // # live cells == size of map.  Must be first (used by len() builtin)
	flags     uint8
	B         uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
	noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
	hash0     uint32 // hash seed

	buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
	oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
	nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)

	extra *mapextra // optional fields
}
代码语言:txt
AI代码解释
复制
	// flags
	iterator     = 1 // there may be an iterator using buckets
	oldIterator  = 2 // there may be an iterator using oldbuckets
	hashWriting  = 4 // a goroutine is writing to the map
	sameSizeGrow = 8 // the current map growth is to a new map of the same size

写入

  • 向map中新增元素最终会调用mapassign函数,在新增操作开始之前就会检验flagshashWriting位是否为1,为1则会报错。
  • 检验通过后会将该位置为1,标记当前正在写入。
  • 写入完成后将该位置为0
代码语言:txt
AI代码解释
复制
// Like mapaccess, but allocates a slot for the key if it is not present in the map.
func mapassign(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {

    ...
    
	if h.flags&hashWriting != 0 {
		throw("concurrent map writes")
	}
	hash := t.hasher(key, uintptr(h.hash0))

	// Set hashWriting after calling t.hasher, since t.hasher may panic,
	// in which case we have not actually done a write.
	h.flags ^= hashWriting

	...
done:
	if h.flags&hashWriting == 0 {
		throw("concurrent map writes")
	}
	h.flags &^= hashWriting

    ...

读取

读取数据的过程相对简单,在读取之前判断是否有置位,校验通过则可以进行读操作,读操作时不会进行置位的。

这也是为啥,如果一个map被初始化ok之后,只要不做增删改,并发读报错的。

代码语言:txt
AI代码解释
复制
// mapaccess1 returns a pointer to h[key].  Never returns nil, instead
// it will return a reference to the zero object for the elem type if
// the key is not in the map.
// NOTE: The returned pointer may keep the whole map live, so don't
// hold onto it for very long.
func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
	...
	if h.flags&hashWriting != 0 {
		throw("concurrent map read and map write")
	}
	...
}

结论

1.看过源码之后,发现这很像一个读写锁,但是并不会造成任何阻塞,有问题直接throw

2.如果真的有初始化一次之后,一直并发读的场景,可以大胆使用map。

常见解决方案

1.自己加锁读。

2.使用sync.map替代(看过一点原理,写数据时实现了加锁;使用了空间换时间的方式,用两个哈希结构存储Map,有一层缓存,加速读取数据。)

3.使用二维切片替代,将key和index做映射。

#如果有理解不到位或者理解失误的地方~欢迎指正~~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
数字化转型:有了CRM后,还需要建设CDP吗?
数字化转型如火如荼,各种系统各种名称眼花缭乱,CRM、DMP、CDP、MA、SCRM、ERP傻傻分不清,CRM系统在信息化时代就已经被广泛接受并使用,在当下数字化营销的新需求之下,很多人会疑惑,我们公司现在已经有了CRM系统,那么到底要不要再搞一套CDP呢?
数据干饭人
2022/12/05
9240
数字化转型:有了CRM后,还需要建设CDP吗?
CDP、DMP、CRM这些概念到底还有没有边界了!
企业数据的管理工具被赋予了不同的名字——CDP、DMP、CRM、SCRM等等,而这些名字背后本来的含义与界限,则被混淆,甚至是故意混淆。
iCDO互联网数据官
2019/05/17
1.3K0
CDP、DMP、CRM这些概念到底还有没有边界了!
CDP平台赋能精细化运营实践
互联网下半场,流量红利过后,流量获取成本越来越昂贵,企业纷纷数字化转型,以期通过大数据的能力充分挖掘流量价值,实现用户与营收的增长。近两年很多行业受疫情冲击严重,比如OTA业务,海外严重萎缩,国内出游也深受时不时爆发的疫情的困扰,增长放缓只能勒紧裤腰带,开源节流了,一分钱当一块钱十块钱花。业务运营方面,需要更加精细化、精准化,提升运营的ROI以及流量的利用效率。
数据干饭人
2022/07/01
1.6K0
CDP平台赋能精细化运营实践
什么是客户数据平台(CDP)?
客户数据平台(Customer Data Platform)是面向业务增长以消费者为中心的客户数据赋能平台,用于收集和统一来自多个来源的第一方客户数据,将来自不同场景、不同渠道的实时数据和离线数据进行采集、整合、分析和应用。帮助企业获取、管理和应用私域数据,打破数据孤岛,连接上下游,建立统一、全面的数据视图,赋能业务以数据驱动业务数字化全链路营销和深度运营,实现业务增长。
产品言语
2022/11/14
1.7K0
自如用户画像平台建设实践与营销应用
二是分享自如的达芬奇·用户画像平台的建设实践,帮助大家从整到分地了解用户画像的建设过程,以及应有的功能模块;
肉眼品世界
2021/11/10
2.4K0
自如用户画像平台建设实践与营销应用
【案例】春秋航空——AI+CDP打造航空业数智化营销平台
“本项目案例由 创略科技 投递并参与由数据猿&上海大数据联盟联合推出的“行业盘点季之数智化转型升级”大型主题策划活动之《2021中国企业数智化转型升级创新服务企业》榜单/奖项的评选。
数据猿
2021/09/01
1.8K0
【案例】春秋航空——AI+CDP打造航空业数智化营销平台
CDP-客户数据平台
David Raab 在2013年首次提出了Customer Data Platform (CDP)的概念。
chimchim
2022/11/13
2.7K0
CDP-客户数据平台
3个迹象表明,企业是时候搭建CDP了!
和过去任何时代相比,当下的数字化程度都更加深入,且还在持续加速的进程中。如今,客户数据的重要性已经毋庸置疑。企业应该如何应用数字化改进客户体验,以及由此产生的海量客户数据,已经成为新的焦点。许多企业通过使用客户数据平台(CDP),游刃有余地驾驭了众多品牌和客户的复杂数据。那么问题来了,CDP是每个企业都必备的吗?哪些迹象标志着企业真正需要CDP? 在服务了数百家企业之后,我们发现了三个常见迹象,表明企业是时候需要搭建CDP来更好地发挥客户数据价值了。
用户1094615
2023/04/23
4080
搞不懂DMP是什么?看这里就够了
近年来,随着移动互联网和信息时代的不断发展,大数据技术在各行各业的作用也日益显著。在营销领域,大数据技术应用从精准营销、闭环营销扩展到了消费者价值挖掘、消费者全生命周期运营,并且与各行业的个性化营销场景结合,发挥着其越来越大的价值。
王知无-import_bigdata
2020/11/24
7.5K0
搞不懂DMP是什么?看这里就够了
数据中台:从0-1,数据服务平台(DMP)实践
看过很多关于如何构建用户画像的文章,大多聚焦于用户画像对精准营销、精细化运营的价值、如何建设标签体系的某一或某几个点,本文主要从数据中台思想出发,更全面地分享如何从0-1规划和实施一款智能数据服务平台。
数据干饭人
2022/07/01
1.5K0
数据中台:从0-1,数据服务平台(DMP)实践
CDP客户数据管理平台体系化搭建
客户数据平台(Customer-Data-Platform),简称CDP;通过采集多方客户数据(主体与线索)等,从而进行精准的客户分析和人群细分,进而实现高效的客户维系和发掘以及日常营销运营。
知了一笑
2021/11/12
1.3K0
CDP客户数据管理平台体系化搭建
激活私域数据,企业如何打造自己的数据银行
A品牌是一家3C集团品牌,近年来,随着电商的发展,在拓展线下渠道的同时,也在开拓线上资源。他们希望在有限的预算下使广告尽可能覆盖到更多的目标用户,并且提升用户与广告互动的可能性。经过多年线上线下的同步发展,A品牌积累了大量的数据,其数据来源主要包括CRM、售后服务、App、施行实名制的社区,以及通过官网、自有电商网站、数字广告、线下零售店和线下活动等等。
iCDO互联网数据官
2019/07/31
1.1K0
用户标签&营销体系的客户数据平台(CDP)建设
CDP(Customer Data Platform,客户数据平台)是由营销人管理的客户数据库,将来自不同渠道、不同场景的实时和非实时的客户数据进行采集、整合、分析和应用,以实现客户建模、设计营销活动、提升营销效率和优化客户体验的目标,从而促进企业业绩及利润的增长。接下来跟大家聊聊为什么需要建设 CDP;我们应该怎么去建设 CDP;最后是建设 CDP 我们需要做什么。
王知无-import_bigdata
2021/07/30
4.5K0
LinkFlow CDP科普篇01:客户数据平台(CDP)是什么?
所有人都想从最基本的开始做起,了解客户是谁。这似乎很简单, 但客户与业务互动渠道的激增使得这个简单的目标变得极其复杂。
用户1094615
2023/04/21
6860
CDP实操篇04:购置CDP需要评估哪些价值点?
前不久,Gartner发布了最新的数字营销和广告宣传周期报告,显示客户数据中台(CDP)可能改变营销人员对技术生态系统的运行方式。这一观点将CDP推向了数字化营销的浪潮之巅,不少企业都希望能采购一个CDP来实现营销效果的升华。
用户1094615
2023/04/23
2970
DMP101 之五:DMP vs CDP,它们到底有没有区别
在DMP概念正火的时候,又杀出来一个新的名词CDP。很多朋友问我,CDP是DMP吗?
iCDO互联网数据官
2019/10/08
1.1K0
DMP101 之五:DMP vs CDP,它们到底有没有区别
3分钟告诉你什么是CDP系统!
实体零售行业正在悄然变革,零售企业数字化转型进程不得不加快,市场环境不断发生转变,数字化升级是零售企业的必经之路。而数字化之路也在这期间产生了很多变化,其中就包括了CDP。
博阳SCRM系统
2022/04/12
1.5K0
3分钟告诉你什么是CDP系统!
【iCDO专访】数据掌门人王琤:关于CDP的那些事儿
Convertlab联合创始人兼CTO,致力于为国内企业提供先进的数字营销SaaS产品。之前服务于SAP中国超过10年,作为产品总监在SAP管理近300人规模的产品研发和产品管理团队,从无到有打造了SAP全新一代SaaS产品SAP Anywhere。拥有近20年企业服务软件研发、咨询与实施、项目管理、产品管理、团队管理等经验。早期专注于面向大型企业的ERP,CRM、BI产品和全球客户,近几年专注于SaaS产品、数字营销和中国市场。
iCDO互联网数据官
2018/12/05
1.2K0
基于POI和地理围栏的精细化运营实践
记得大学时,每年暑期开学,校园里各个运营商摊位卖手机、卖号卡,毕业工作后,互联网浪潮兴起,中午办公园区吃饭看到路边各种小桌子、小推车进行App应用地推,注册新用户发个小礼物。其实,不管是居民区扫楼发传
数据干饭人
2022/07/01
7800
基于POI和地理围栏的精细化运营实践
从缔造到升阶,酷开网络OTT营销生态让大屏价值开疆拓土
而在移动互联网、传统户外媒体激烈搏杀时,一股新兴的广告营销力量在“不经意间”快速崛起——OTT营销开始成为许多广告主的选择。
曾响铃
2019/08/07
4370
从缔造到升阶,酷开网络OTT营销生态让大屏价值开疆拓土
推荐阅读
相关推荐
数字化转型:有了CRM后,还需要建设CDP吗?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档