最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語言map不支持并發(fā)寫操作的原因

 更新時間:2024年01月01日 11:12:34   作者:frank  
Go語言為什么不支持并發(fā)讀寫map?,Go官方的說法是在多數(shù)情況下map只存在并發(fā)讀操作,如果原生支持并發(fā)讀寫,即降低了并發(fā)讀操作的性能,在使用?map?時,要特別注意是否存在對?map?的并發(fā)寫操作,如果存在,要結合?sync?包的互斥鎖一起使用,

本文介紹 Go 語言為什么不支持并發(fā)讀寫 map?,Go 官方的說法是在多數(shù)情況下 map 只存在并發(fā)讀操作,如果原生支持并發(fā)讀寫,即降低了并發(fā)讀操作的性能。在使用 map 時,要特別注意是否存在對 map 的并發(fā)寫操作,如果存在,要結合 sync 包的互斥鎖一起使用。

01 、介紹

在 Go 語言項目開發(fā)中,我們經(jīng)常會使用哈希表 map,它的時間復雜度是 O(1),Go 語言中的 map 使用開放尋址法避免哈希碰撞。

Go 語言中的 map 并非原子操作,不支持并發(fā)讀寫操作。

Go 官方認為 map 在大多數(shù)情況下是使用 map 進行并發(fā)讀操作,僅在少數(shù)情況下是使用 map 進行并發(fā)讀寫操作。

如果 Go 語言中的 map 原生支持并發(fā)讀寫操作,在操作時需要先獲取互斥鎖,反而會降低只有并發(fā)讀操作時的性能。

在需要并發(fā)讀寫操作 map 時,可以結合 sync 包中的互斥鎖一起使用。

02 、并發(fā)讀寫 map

Go 支持并發(fā)讀 map,不支持并發(fā)讀寫 map。

示例代碼:

func main() {
 var m = make(map[int]string)

 go func() {
  for {
   m[1] = "xx"
  }
 }()

 go func() {
  for {
   _ = m[1]
  }
 }()
 time.Sleep(time.Second * 3)
}

輸出結果:

fatal error: concurrent map read and map write
// ...

閱讀上面這段代碼,我們并發(fā)讀寫 map 類型的變量 m,在運行時,返回致命錯誤 fatal error: concurrent map read and map write。

Go 語言中的 map 在運行時是怎么檢測到 map 的存在寫操作?

源碼:

const (
 // flags
 iterator     = 1 // there may be an iterator using buckets
 oldIterator  = 2 // there may be an iterator using oldbuckets
 hashWriting  = 4 // a goroutine is writing to the map
 sameSizeGrow = 8 // the current map growth is to a new map of the same size
)
// A header for a Go map.
type hmap struct {
 count     int // # live cells == size of map.  Must be first (used by len() builtin)
 flags     uint8
 B         uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
 noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
 hash0     uint32 // hash seed

 buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
 oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
 nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)

 extra *mapextra // optional fields
}

// Like mapaccess, but allocates a slot for the key if it is not present in the map.
func mapassign(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
 // ...

done:
 if h.flags&hashWriting == 0 {
  fatal("concurrent map writes")
 }
 h.flags &^= hashWriting
 if t.IndirectElem() {
  elem = *((*unsafe.Pointer)(elem))
 }
 return elem
}

閱讀上面這段源碼,我們可以發(fā)現(xiàn)在 hmap 結構體中的字段 flags,該字段用于標記 map 是否為寫入狀態(tài)。

在訪問 map 時,通過判斷 hmap.flags 和 hashWriting 的值,可知是否有其它 goroutine 訪問 map,如果有,則返回致命錯誤 fatal("concurrent map writes")。

03 、總結

本文介紹 Go 語言為什么不支持并發(fā)讀寫 map,Go 官方的說法是在多數(shù)情況下 map 只存在并發(fā)讀操作,如果原生支持并發(fā)讀寫,即降低了并發(fā)讀操作的性能。

通過閱讀源碼,我們了解到在運行時檢測是否存在其它 goroutine 對 map 的寫操作,如果存在,則返回致命錯誤。

讀者朋友們在使用 map 時,要特別注意是否存在對 map 的并發(fā)寫操作,如果存在,要結合 sync 包的互斥鎖一起使用。

到此這篇關于Go語言map不支持并發(fā)寫操作的原因的文章就介紹到這了,更多相關Go中map不支持并發(fā)寫內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Go語言普通指針unsafe.Pointer?uintpt之間的關系及指針運算

    Go語言普通指針unsafe.Pointer?uintpt之間的關系及指針運算

    這篇文章主要為大家介紹了Go語言普通指針unsafe.Pointer?uintpt之間的關系及指針運算示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Golang中的new()和make()函數(shù)本質區(qū)別

    Golang中的new()和make()函數(shù)本質區(qū)別

    在 Go 語言開發(fā)中,new() 和 make() 是兩個容易讓開發(fā)者感到困惑的內建函數(shù),盡管它們都用于內存分配,但其設計目的、適用場景和底層實現(xiàn)存在本質差異,本文將通過類型系統(tǒng)、內存模型和編譯器實現(xiàn)三個維度,深入解析這兩個函數(shù)的本質區(qū)別,感興趣的朋友一起看看吧
    2025-02-02
  • Go語言編譯原理之變量捕獲

    Go語言編譯原理之變量捕獲

    這篇文章主要為大家介紹了Go語言編譯原理之變量捕獲示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Go defer與time.sleep的使用與區(qū)別

    Go defer與time.sleep的使用與區(qū)別

    本文主要介紹了Go defer與time.sleep的使用與區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-04-04
  • 淺析Go語言中的逃逸分析

    淺析Go語言中的逃逸分析

    逃逸分析算是go語言的特色之一,所以這篇文章小編就來和大家聊聊為什么不應該過度關注go語言的逃逸分析,感興趣的小伙伴可以跟隨小編一起了解一下
    2024-10-10
  • 詳解Go語言中配置文件使用與日志配置

    詳解Go語言中配置文件使用與日志配置

    這篇文章主要為大家詳細講解一下Go語言中調整項目目錄結構、增加配置文件使用和增加日志配置的方法,文中示例代碼講解詳細,需要的可以參考一下
    2022-06-06
  • 如何在golang中使用shopspring/decimal來處理精度問題

    如何在golang中使用shopspring/decimal來處理精度問題

    本文主要介紹了如何在golang中使用shopspring/decimal來處理精度問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • Go?語言sort?中的sortInts?方法

    Go?語言sort?中的sortInts?方法

    這篇文章主要介紹了Go?語言sort?中的sortInts?方法,Go?的?sort?包實現(xiàn)了內置和用戶定義類型的排序。我們將首先查看內置函數(shù)的排序,西瓦嗯更多相關資料需要的小伙伴可以參考一下
    2022-04-04
  • Go?語言?net/http?包使用之HTTP?服務器、客戶端與中間件詳解

    Go?語言?net/http?包使用之HTTP?服務器、客戶端與中間件詳解

    Go 語言標準庫中的net/http包十分的優(yōu)秀,提供了非常完善的 HTTP 客戶端與服務端的實現(xiàn),僅通過幾行代碼就可以搭建一個非常簡單的 HTTP 服務器,本文給大家介紹Go語言net/http包使用之HTTP服務器、客戶端與中間件的操作,感興趣的朋友一起看看吧
    2025-05-05
  • Go通過goroutine實現(xiàn)多協(xié)程文件上傳的基本流程

    Go通過goroutine實現(xiàn)多協(xié)程文件上傳的基本流程

    多協(xié)程文件上傳是指利用多線程或多協(xié)程技術,同時上傳一個或多個文件,以提高上傳效率和速度,本文給大家介紹了Go通過goroutine實現(xiàn)多協(xié)程文件上傳的基本流程,需要的朋友可以參考下
    2024-05-05

最新評論

黄大仙区| 邹城市| 苍山县| 苏州市| 云安县| 锡林郭勒盟| 宜宾县| 泗水县| 镇平县| 新龙县| 揭西县| 留坝县| 西峡县| 浦北县| 丹江口市| 怀安县| 田林县| 南康市| 治多县| 墨竹工卡县| 定襄县| 林西县| 辛集市| 汉源县| 临海市| 调兵山市| 电白县| 望城县| 富顺县| 浦东新区| 定安县| 洛扎县| 日照市| 繁昌县| 远安县| 高淳县| 石屏县| 景谷| 白河县| 竹北市| 吉林省|