Golang初學:高併發時寫入資料到不同的map

快乐的凡人721發表於2024-05-14

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”錯誤。

Golang初學:高併發時寫入資料到不同的map

測試#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.

Golang初學:高併發時寫入資料到不同的map

END.

ben釋出於部落格園

本文連結:

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

ben釋出於部落格園

參考資料

1、

ben釋出於部落格園

ben釋出於部落格園

相關文章