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

 

posted @ 2024-05-14 06:06  快乐的欧阳天美1114  阅读(29)  评论(0编辑  收藏  举报