golang 一种并发安全 map 的实现

go并发访问map的坑 fatal error: concurrent map read and map write 前言 go 并发访问map是不安全的, 会出现未定义的错误导致程序退出…坑总得踩一踩才会知道 例子 先写一个错误的 package main import "fmt" func test() map[string]interface{}{ taskList := []string{"a", "b"} result := make(map[string]interface{}) for _... 阅读详情

在 Go 语言的并发编程场景中,标准库中的map类型并不是并发安全的。当多个 goroutine 同时对map进行读写操作时,很容易引发竞态条件(race condition),导致程序出现不可预测的错误。为了解决这一问题,我们可以通过自定义结构体,结合读写锁来实现一个并发安全的map,本文就来详细介绍一种安全map的实现方法。​

代码实现​

package main

import (
	"sync"
)

type safeMap struct {
	lock *sync.RWMutex
	sm   map[interface{}]interface{}
}

func newSafeMap() *safeMap {
	return &safeMap{
		lock: new(sync.RWMutex),
		sm:   make(map[interface{}]interface{}),
	}
}

func (m *safeMap) Get(k interface{}) interface{} {
	m.lock.RLock()
	defer m.lock.RUnlock()
	if val, ok := m.sm[k]; ok {
		return val
	}
	return nil
}

func (m *safeMap) Set(k interface{}, v interface{}) bool {
	m.lock.Lock()
	defer m.lock.Unlock()
	if val, ok := m.sm[k]; !ok {
		m.sm[k] = v
	} else if val != v {
		m.sm[k] = v
	} else {
		return false
	}
	return true
}

func (m *safeMap) Check(k interface{}) bool {
	m.lock.RLock()
	defer m.lock.RUnlock()
	if _, ok := m.sm[k]; !ok {
		return false
	}
	return true
}

func (m *safeMap) Delete(k interface{}) {
	m.lock.Lock()
	defer m.lock.Unlock()
	delete(m.sm, k)
}
golang--sync.map(安全字典) sync.Map是一种并发安全的映射数据结构,它提供了高效的并发访问方式,避免了显式的锁操作。在编写多个goroutine并发访问共享数据的程序时,使用sync.Map能够简化并发编程的复杂性,提高程序的性能和可靠性。相比于传统的map类型,sync.Map的设计目标是提供高效的并发读写操作,尤其适用于读多写少的场景。2.无需加锁:与传统的map不同,sync.Map使用了一种特殊的并发安全算法,避免了锁的使用。3.动态增长:sync.Map可以动态地增长和收缩内部的数据结构,以适应不同的并发负载。 阅读详情

相关推荐

组合导航(八):INS/GPS组合导航

INS/GPS组合导航1 误差反馈1.1 开环INS/GPS架构1.2 闭环INS/GPS架构2 组合导航的类型2.1 松耦合 的INS/GPS组合导航2.2 紧耦合 的INS/GPS组合导航2.3 深度耦合的 INS/GPS组合导航3 INS方程的动态误差模型4 松耦合的INS/GPS组合导航模型4.1 系统模型4.2 测量模型4.3 INS/GPS松耦合总框图5 紧耦合的INS/GPS组合导航模型5.1 系统模型5.2 测量模型 INS/GPS组合导航 对比INS与GPS导航方法,二者都有其各自的优.

weixin_43793960的博客 3万+

golang线程安全的map

github地址:https://github.com/hackssssss/safemap 网上找的协程安全的map都是用互斥锁或者读写锁实现的,这里用单个协程来实现下,即所有的增删查改操作都集成到一个goroutine中,这样肯定不会出现多线程并发访问的问题。 基本思路是后台启动一个长期运行的goroutine,阻塞的接受自己channel中的请求req,req分为不同的请求,比如读key...

liyunlonghere 3万+

Altair HyperWorks 2022.3.0 Suite下载

Altair HyperWorks开发团队提供了新的一流技术,以设计和优化高性能、高效和创新的产品,并发布了HyperWorks 2021.2套件。与所有新版本一样,这个版本包含了新特性、增强功能,并修复了前一个版本中用户报告的各种问题,提供了总体上更稳定的体验。链接: https://pan.baidu.com/s/1rYietmQLQUboHiJzYoE9WQ?pwd=m9yh 提取码: m9yh 复制这段内容后打开百度网盘手机App,操作更方便哦。

weixin_48469365的博客 2127

Golang 并发安全Map容器实践

你好,我是俞凡,在Motorola做过研发,现在在Mavenir做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。在读取或写入map前锁定mutex,并在读取或写入map后解锁mutex。

残星说梦话 653

如何打开本地网络的防火墙端口(Windows版)解决ConnectionRefusedError: [WinError 10061] 由于目标计算机积极拒绝,无法连接。问题

ConnectionRefusedError: [WinError 10061] 由于目标计算机积极拒绝,无法连接。 最开始在遇到这个报错的时候十分不解,后来经过思考,有可能是服务器端口占用,或者并没有放行。因此搜查问题的关键是要先去排查问题。 在搜索栏输入控制面板 选择防火墙 选择开关 保证这些选项是开着的 选择高级设置 新建规则 创建协议端口 选择端口 允许连接 点击下一步 创建规则后点击下一步(后命名) 选择任意端口ALL即可 问题排查完毕!socket创建网络通信时,有读者

weixin_46900108的博客 9万+

Android AudioFlinger(一)——初识AndroidAudio Flinger

AudioFlinger 是 Android 系统中的音频中间层(audio HAL, Audio Hardware Abstraction Layer)的一部分,负责管理音频的混音、播放和音量控制等功能。它充当 Android 应用程序和音频硬件之间的桥梁。

hirezy 1669

golang线程安全map

golang安全map使用 使用内置sync.Map 使用读写锁实现并发安全map 读写锁实现并发安全map import ( "sync" ) // SyncMap is a map with lock type SyncMap struct { lock *sync.RWMutex bm map[interface{}]interface{} } // NewSyncMap return new safemap func NewSyncMap() *SyncMap { return

elecjun的博客 1085

Python 爬虫实战:爬取微博热搜与用户评论数据

本文系统讲解微博热搜榜单与用户评论数据的爬取技术方案。针对微博热搜榜采用Requests+BeautifulSoup解析静态HTML结构,实现高效爬取;对于动态加载的评论数据,使用Selenium模拟浏览器行为规避反爬机制。详细阐述技术选型、反爬策略、数据清洗及存储方法,提供完整代码实现和输出示例。同时强调合规要求,提示开发者需在遵守平台规则的前提下进行数据采集。该方案为舆情分析和热点研究提供了可落地的技术实现路径。

2503_91057718的博客 1716

golang 1.8 并发安全Map简单实现

type SafeMap struct { sync.RWMutex Map map[int64]string } func NewSafeMap(size int) *SafeMap { sm := new(SafeMap) sm.Map = make(map[int64]string, size) return sm } func (sm *Safe...

wwhhff11 2211

操作系统实验四 进程运行轨迹的跟踪与统计(哈工大李治军)

实验4 进程运行轨迹的跟踪与统计 实验目的 掌握 Linux 下的多进程编程技术; 通过对进程运行轨迹的跟踪来形象化进程的概念; 在进程运行轨迹跟踪的基础上进行相应的数据统计,从而能对进程调度算法进行实际的量化评价,更进一步加深对调度和调度算法的理解,获得能在实际操作系统上对调度算法进行实验数据对比的直接经验。 实验内容 进程从创建(Linux 下调用 fork())到结束的整个过程就是进程的生命期,进程在其生命期中的运行轨迹实际上就表现为进程状态的多次切换,如进程创建以后会成为就绪态;当该进程被调度以

leoabcd12的博客 4653

【Segment Anything Model】三:SAM模型微调自定义数据集,更改混合提示方式:点,框,点框混合

1.微调SAM预备知识。

cvxiayixiao的博客 1万+

go 并发安全map 分段锁实现

一. 简言 1.1 go中的map不是并发安全的 1.2 go1.9版本之前,可以使用map+mutex的方式实现并发安全,但是每次操作,无论读取都要加锁,性能不太好 1.3 go 1.9之后,新增了sync.Map,是并发安全的,效率也很高,具体的源码分析可见笔者的另外一篇博客 https://blog.csdn.net/yzf279533105/article/deta...

papaya的博客 3240

DC Error: The power pin VDD on the cell UASA1/CG_X8_Rdsd2pcm is unconnected. (UPF-581)

【代码】DC Error: The power pin VDD on the cell UASA1/CG_X8_Rdsd2pcm is unconnected. (UPF-581)

baidu_34971492的博客 970

GO map(集合)

GO MAP(集合),键值对是否存在,map顺序遍历,map实现原理,map底层数据结构,hash冲突,拉链法,开放寻址法,map并发不安全

weixin_39171666的博客 2258

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

记录几个go的工具,协程安全Map和Map,slice,struct及其指针类型Copy

deepCopy 可以完成map,slice,strcut以及相对应的指针类型的Copy func deepCopy(dst, src reflect.Value) { switch src.Kind() { case reflect.Interface: value := src.Elem() if !value.IsValid() { return } newVa...

地球流浪猫的博客 512

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Go语言map的详解(第二篇)之并发安全的sync.Map

sync.Map的底层结构,底层的原理,以及优缺点

Dong_chongwu的博客 2446

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

深入理解golang:sync.map

疑惑开篇# 有了map为什么还要搞个sync.map 呢?它们之间有什么区别? 答:重要的一点是,map并发不是安全的。 在Go 1.6之前, 内置的map类型是部分goroutine安全的,并发的读没有问题,并发的写可能有问题。自go 1.6之后, 并发地读写map会报错,这在一些知名的开源库中都存在这个问题,所以go 1.9之前的解决方案是额外绑定一个锁,封装成一个新的struct或者单独使用锁都可以。 go version go1.13.9 windows/amd64 测试一波# 写一个简单的并发写m

m0_50071460的博客 955

[Go] 使用读写锁对map资源进行安全处理

当需要有一个全局性的map集合资源进行增删改数据时,需要对该map资源增加读写锁,防止并发时出现安全问题 下面的类就是举例 , 属性中的Conns模拟存储一些资源,对这些资源进行并发的增加数据,使用写锁锁住资源,当读取是使用读锁锁住资源 package snet import "sync" import "errors" type ConnManger stru...

程序员老狼专注开发aigc或客服系统应用 234

golang的Map读写锁

package main import ( "fmt" "sync" "time" ) type ConcurMap struct { Data map[string]int Lock *sync.RWMutex } func NewConcurMap() *ConcurMap{ return &ConcurMap{ Data: make(map[string]int), Lock:&sync.RWMutex{}, } } func (d ConcurMap)

qq_30505673的博客 3174

Go实现阻塞读且并发安全的map

读的时候如果值不存在则阻塞,直到写入值,那么每个键值需要有一个阻塞。,题目中要求并发安全,那么必须用锁,还要实现多个。看到阻塞协程第一个想到的就是。

linzhongshu的专栏 413

Golang中sync.Map的实现原理

前言 前面,我们讲了map的用法以及原理Golang中map的实现原理,但我们知道,map在并发读写的情况下是不安全。需要并发读写时,一般的做法是加锁,但这样性能并不高,Go语言在 1.9 版本中提供了一种效率较高的并发安全的 sync.Map,今天,我们就来讲讲 sync.Map的用法以及原理 使用方法 func main() { var m sync.Map //插入 m.Store("1","a") //取值 fmt.Println(m.Load("1")) //删除 m.Delete(

香烟,瓜子,矿泉水 3033

sync.Map详解

从源码了解sync.Map

yuchenfw的博客 2221

golang map 锁_[入门] golang下Map的使用和性能分析(勿滥用锁)

golang 中 map 性能优化[低阶]简单介绍golang 中的 build-in 的 map 这个 map 是非线程安全的,但是也是最常用的一个家伙。 为了测试多个 map 的性能我写了个接口 Maptype Map interface {Set(key interface{}, val interface{})Get(key interface{}) (interface{}, bool)...

weixin_30306285的博客 241

【go面试】数组、slice、map、channel

由于map中不断的put和delete key,桶中可能会有很多断断续续的空位,这些空位会导致连接的bmap溢出桶很长,导致扫描的时间变长。map使用的拉链法,从前朝后找到一个空位,插入进去,如果8个kv满了,就会链接到下一个溢出桶bmap中。Bucket数组中每个元素都是bmap结构,也就是桶的结构,每个桶中有8个k-v对,如果8个满了,就会使用overflow连接下一个桶(溢出桶)Slice的底层结构是一个指向数组的指针和长度len、容量cap构成,Slice的数据实际是存在数组中的。

weixin_43885656的博客 383
上一篇: OpenSSL 1.1.1q 交叉编译
下一篇: Go 语言跨平台编译方法
mxpan
博客等级 码龄18年 176粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mxpan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值