Go 中高效的共享映射實現技術
對共享資料結構的並發存取需要仔細考慮以確保資料完整性。考慮一個映射被多個 goroutine 同時存取的情況,如下例所示。
<code class="go">func getKey(r *http.Request) string { ... } values := make(map[string]int) http.HandleFunc("/get", func(w http.ResponseWriter, r *http.Request) { key := getKey(r) fmt.Fprint(w, values[key]) }) http.HandleFunc("/set", func(w http.ResponseWriter, r *http.Request) { key := getKey(r) values[key] = rand.Int() })</code>
透過並發寫入直接操作映射可能會導致資料不一致。如下所示,使用互斥體可以解決原子性問題,但會帶來另一個問題。
<code class="go">func getKey(r *http.Request) string { ... } values := make(map[string]int) var lock sync.RWMutex http.HandleFunc("/get", func(w http.ResponseWriter, r *http.Request) { key := getKey(r) lock.RLock() fmt.Fprint(w, values[key]) lock.RUnlock() }) http.HandleFunc("/set", func(w http.ResponseWriter, r *http.Request) { key := getKey(r) lock.Lock() values[key] = rand.Int() lock.Unlock() })</code>
雖然互斥體提供可靠的同步,但它們引入了手動鎖定和解鎖的複雜性。 Go 中較慣用的方法是利用通道。預設情況下,建議優先考慮通道而不是互斥體,正如Go 的座右銘所例示的:「透過通訊共享內存,不要透過共享記憶體進行通訊。」
以下是一些關鍵注意事項:
以上是如何應用Go的並發原理來創建安全高效的共享地圖?的詳細內容。更多資訊請關注PHP中文網其他相關文章!