[GO]MAP的併發問題
#
GOLANG的MAP的併發問題- contain a special check that automatically reports at run time when a map is modified unsafely by concurrent execution.
- Map程式執行會報錯誤
關於map的競爭解法說明 慎用golang中的map,特别是在并发操作中
golang-fatal-error-concurrent-map-read-and-map-write
- 需要併發讀寫時,一般的做法是加鎖,但這樣效能並不高,Go語言在 1.9 版本中提供了一種效率較高的併發安全的 sync.Map
#
sync.Map的用法以及原理為什麼 Go Map 和 Slice 是非線性安全的? 其實Slice也是非線性安全,但需自行處理之, Go 語言的 sync.Map 支援併發讀寫 map,採取了 “空間換時間” 的機制,但預設的Map不支援,Go 官方在經過了長時間的討論後,認為 Go map 更應適配典型使用場景。
不适用于大量写的场景,这样会导致read map读不到数据而进一步加锁读取,同时dirty map也会一直晋升为read map,整体性能较差。sync.Map适用场景:大量读,少量写與證明
TBD: 從解說看來syncmap.Map似乎更適合用於有loop read map時,但是如果是大量寫,少量讀也是嗎?從解說看來是,但不確定該說的大量比率如何詮釋,待研究確認。
i <= 100 end:98.0947msalloc [280272] heapAlloc [280272] HeapInuse [950272] Goroutine[3] Update Unlock end:1m40.0204304salloc [303160] heapAlloc [303160] HeapInuse [802816] Goroutine[3]
目的: 需要維護不同的非同步工作(job),並記錄最後的完成時間。 另一方面,需要定期去查看所有工作的最後完成時間並做紀錄上傳,上傳後即刪除目前維護的時間。
遇到問題: 知道如果非同步存取相同的變數會有data race的問題,透過go run -race可檢測。
解決方法: 1.使用鎖 2.使用syncMap
結果: 方法1竟然鎖不住? 追查結果是因為重複create map 變數的地方有問題 方法2成功
方法二: sync.Map,該包中的Map提供了Store、Load、Delete、Range等操。並且sync包中的Map是開箱可用的,也即是聲明後就可以直接使用