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 #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发布于博客园