在Go 中,對共享映射的並發訪問需要仔細考慮以避免非原子寫入。雖然可以使用互斥體,但它們引入了可能與慣用的 Go 方法不一致的原語的使用。
一種替代方法是利用通道進行並發控制。這種方法符合「透過通訊來共享內存,而不是透過共享記憶體來通訊」的 Go 哲學。 goroutine 可以透過通道進行通信,而不是直接操作映射,從而確保對共享資料的獨佔存取。
例如,在原始程式碼中,可以進行以下修改:
<code class="go">// key retrieval logic remains the same values := make(map[string]int) var valueCh = make(chan string) var setCh = make(chan map[string]int) // Handler for GET requests http.HandleFunc("/get", func(w http.ResponseWriter, r *http.Request) { key := getKey(r) valueCh <- key fmt.Fprint(w, <-valueCh) }) // Handler for SET requests http.HandleFunc("/set", func(w http.ResponseWriter, r *http.Request) { key := getKey(r) tmp := make(map[string]int) tmp[key] = rand.Int() setCh <- tmp }) // Map update goroutine go func() { for { select { case key := <-valueCh: valueCh <- values[key] case updatedMap := <-setCh: for k, v := range updatedMap { values[k] = v } } } }()</code>
在這個修改後的程式碼中:
透過採用這種基於通道的方法,程式碼變得更加慣用,簡化了並發管理,並遵循 Go 原則避免共享記憶體。
以上是通道如何透過共享地圖增強 Go 中的並發性?的詳細內容。更多資訊請關注PHP中文網其他相關文章!