Golang初学:高并发时写入数据到不同的map
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_000
	const num2 = 10_000
	for 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_000
	const num2 = 10_000
	for 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 #3:  10000000 | 
用到的函数:计算长度
// 计算 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发布于博客园
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号