Golang初学:高并发时写入数据到不同的map

news/2024/9/23 11:21:28

go version go1.22.1 windows/amd64

Windows 11 + amd64

x86_64 x86_64 GNU/Linux

---

 

序章

多个 给 map 写入数据。

1、基本的map:make(map[any]any)

失败

2、sync.Map

成功

 

测试场景:

1K 个 goroutines 给同一个 map 各自写入 1W 数据,总1KW数据。

 

测试#1:普通map

代码:ben发布于博客园

// 多个 goroutines 写入 多个数据
// 百万+
// 失败
func testMap2() {map0 := make(map[any]any)fmt.Println("len#1: ", len(map0))const num1 = 1_000const num2 = 10_000for i := range [num1]int{} {go func() {for j := range [num2]int{} {key := fmt.Sprintf("k%d#%d", i, j)map0[key] = j // fatal error: concurrent map writes}fmt.Println("go end i=", i)}()}fmt.Println("len#2: ", len(map0))time.Sleep(5 * time.Second)fmt.Println("len#3: ", len(map0)) // 等于 num1 * num2 ?fmt.Println("end.")
}

测试结果:

执行失败,出现了“fatal error: concurrent map writes”错误。

 

测试#2:sync.Map

// 多个 goroutines 写入数据
// 每个写入多个
func testMapForRoutines() {map0ptr := new(sync.Map)prtln("len of map #1: ", LenOfSyncMap(map0ptr))const num1 = 1_000const num2 = 10_000for i := range [num1]int{} {go func() {for j := range [num2]int{} {key := fmt.Sprintf("r#%d#%d", i, j)map0ptr.Store(key, j)}prtln("end#i", i)}()}prtln("len of map #2: ", LenOfSyncMap(map0ptr))// sleepSeconds(10) // 数据 1KW 时,时间不够sleepSeconds(30)prtln("len of map #3: ", LenOfSyncMap(map0ptr))// OutputSyncMap(map0ptr)sleepSeconds(5)prtln("end.")
}

测试结果:ben发布于博客园

len of map #1:  0
len of map #2:  8974
end#i 881
end#i 448
end#i 689

...

len of map #3:  10000000
end.

 

用到的函数:计算长度

// 计算 sync.Map 长度
func LenOfSyncMap(map0 *sync.Map) (len int64) {map0.Range(func(key, value any) bool {len++return true})return
}

注意,这里的返回值 有名称——len,因此,return 后面没有内容。

ben发布于博客园

type sync.Map 简介

https://pkg.go.dev/sync@go1.22.3#Map

具体请看 文档。

描述:

Map is like a Go map[any]any but is safe for concurrent use by multiple goroutines without additional locking or coordination.

Loads, stores, and deletes run in amortized constant time.

 

END.

ben发布于博客园

本文链接:

https://www.cnblogs.com/luo630/p/18190211

 

ben发布于博客园

参考资料

1、

 

ben发布于博客园

ben发布于博客园

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/31251.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Cocos Creator 3.8.x 透明带滚动功能的容器

ScrollView 是一种带滚动功能的容器 1、删除ScrollView下Sprite组件的SpriteFrame 2、ScrollView下scrollBar的Sprite组件的Color设为:FFFFFF00 3、ScrollView下view的Graphics组件的FillColor设为:FFFFFF00

TACO编译器张量与科学计算SpMV

TACO编译器张量与科学计算SpMV 定义张量 声明张量 taco::Tensor对象,对应于数学张量,构成了taco C++API的核心。可以通过指定新张量的名称、包含张量每个维度大小的向量,以及将用于存储张量的存储格式来声明新张量: // Declare a new tensor "A" of double-preci…

让创意在幻觉中肆虐: 认识Illusion Diffusion AI

人工智能新境界在不断发展的人工智能领域,一款非凡的新工具应运而生,它能将普通照片转化为绚丽的艺术品。敬请关注Illusion Diffusion,这是一个将现实与想象力完美融合的AI驱动平台,可创造出迷人的视错觉和超现实意境。 AI算法的魔力所在Illusion Diffusion 的核心是借助先进的…

nfs服务器安装

安装NFS服务 sudo apt-get update sudo apt install nfs-kernel-server检查服务支持的版本 sudo cat /proc/fs/nfsd/versions上面显示支持3/4/4.1/4.2版本,并不支持2版本,在比较新的ubuntu系统上面已经不支持2版本了,如果在挂载nfs服务时相关挂载的版本比较旧时,需要增加参…

自定义bmp图像缩放及在lcd显示屏任意位置显示

在LCD上任意位置显示一张任意大小并且宽高变为原来1/n大小的色深为 24bit的bmp图片 头文件 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <…

树刷题题后感——相对来说概念和公式数量可以和数论比较

在刷题的时候因为概念太多了越刷越懵所以先整理一下。题目来源:牛客网专项练习牛客网专项练习_校招题库练习题_行测题库考点考题 (nowcoder.com)树:参考链接:如何理解数据结构中树的度(树的度是什么意思)?-CSDN博客       (他这里打的“节点数“是指节点,,意思就…

PWM

PWMPWM1. 什么是PWM? 2. 面积等效原理2.1. 什么是面积等效原理? 2.2. 面积等效原理的理解3. 相关概念3.1. 周期和频率 3.2. 占空比4. 总结 参考链接 others1. 什么是PWM? PWM是Pulse Width Modulation的缩写,中文是脉冲宽度调制。 是利用微处理器的数字输出来对模拟电路进行…

02--JS02--高级

JavaScript02: 进阶 一. 变量声明 1.1 变量提升 // 以下代码,或多或少会有些问题的 function fn(){console.log(name);var name = 大马猴; }fn()// 问题: name变量先使用,再定义 这么写代码,在其他语言里. 绝对是不允许的 但是在js里,不但允许,还能执行,为什么呢? 因…