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/[email protected]#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發佈於博客園

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章