在我的代碼中存儲配置的常見模式是受 RWMutex 保護的“map[string]interface{}”,但通常在應用啟動后(可以在多個 go-routine 中觸發),地圖變得完全只讀。所以我有一種感覺,從某個時間點開始,讀取時的 RWMutex 應該是不必要的。此配置映射的示例位于 http://play.golang.org/p/tkbj9DBok_讓我想到這一點的一個事實是,在一些生產代碼中,它實際上以這種方式對共享對象進行了不受保護的訪問(盡管它在初始化后主要是只讀的),我理解使用 RWMutex 進行保護的正常方式,但很有趣部分是這種格式錯誤的代碼在過去幾個月沒有遇到問題。在某個準確的“時間點”之后,寫入從緩存刷新到內存并保證不再需要寫入后,讀取實際上可以在沒有 RWMutex.RLock 的情況下進行,這是真的嗎?如果是,無鎖訪問前的時間點或如何設置條件?
2 回答

LEATH
TA貢獻1936條經驗 獲得超7個贊
只要沒有人修改地圖,多個線程一次讀取它應該是安全的。不幸的是,如果沒有任何鎖定,您將無法確保在您想要更新地圖時沒有其他人正在閱讀地圖。
因此,一種解決方案是永遠不要更新地圖,而是以原子方式替換它。該只讀副本更新算法可以在這里使用。而不是直接訪問地圖,因此您需要取消引用指針才能訪問地圖。要更新它,您可以執行以下操作:
獲取“更新鎖”互斥鎖。
制作地圖的副本。你想手動復制所有的鍵/值:簡單的賦值是行不通的,因為映射是引用類型。
對地圖副本進行更改。
使用
StorePointer
從sync/atomic
包中自動更新指向實時地圖的指針以指向您的新地圖。釋放互斥鎖。
在 (4) 中原子更新之前運行的所有內容都將看到舊地圖,之后的所有內容都將看到新地圖。這些 goroutine 絕不會從正在寫入的地圖中讀取數據,因此不需要RWMutex
.
- 2 回答
- 0 關注
- 246 瀏覽
添加回答
舉報
0/150
提交
取消