日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Go 語言為什么不支持并發讀寫 map?

來源: 責編: 時間:2024-01-02 09:29:55 200觀看
導讀01 、介紹在 Go 語言項目開發中,我們經常會使用哈希表 map,它的時間復雜度是 O(1),Go 語言中的 map 使用開放尋址法避免哈希碰撞。Go 語言中的 map 并非原子操作,不支持并發讀寫操作。Go 官方認為 map 在大多數情況下是使

01 、介紹

在 Go 語言項目開發中,我們經常會使用哈希表 map,它的時間復雜度是 O(1),Go 語言中的 map 使用開放尋址法避免哈希碰撞。4bm28資訊網——每日最新資訊28at.com

Go 語言中的 map 并非原子操作,不支持并發讀寫操作。4bm28資訊網——每日最新資訊28at.com

Go 官方認為 map 在大多數情況下是使用 map 進行并發讀操作,僅在少數情況下是使用 map 進行并發讀寫操作。4bm28資訊網——每日最新資訊28at.com

如果 Go 語言中的 map 原生支持并發讀寫操作,在操作時需要先獲取互斥鎖,反而會降低只有并發讀操作時的性能。4bm28資訊網——每日最新資訊28at.com

在需要并發讀寫操作 map 時,可以結合 sync 包中的互斥鎖一起使用。4bm28資訊網——每日最新資訊28at.com

02 、并發讀寫 map

Go 支持并發讀 map,不支持并發讀寫 map。4bm28資訊網——每日最新資訊28at.com

示例代碼:4bm28資訊網——每日最新資訊28at.com

func main() { var m = make(map[int]string) go func() {  for {   m[1] = "xx"  } }() go func() {  for {   _ = m[1]  } }() time.Sleep(time.Second * 3)}

輸出結果:4bm28資訊網——每日最新資訊28at.com

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

閱讀上面這段代碼,我們并發讀寫 map 類型的變量 m,在運行時,返回致命錯誤 fatal error: concurrent map read and map write。4bm28資訊網——每日最新資訊28at.com

Go 語言中的 map 在運行時是怎么檢測到 map 的存在寫操作?4bm28資訊網——每日最新資訊28at.com

源碼:4bm28資訊網——每日最新資訊28at.com

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}

閱讀上面這段源碼,我們可以發現在 hmap 結構體中的字段 flags,該字段用于標記 map 是否為寫入狀態。4bm28資訊網——每日最新資訊28at.com

在訪問 map 時,通過判斷 hmap.flags 和 hashWriting 的值,可知是否有其它 goroutine 訪問 map,如果有,則返回致命錯誤 fatal("concurrent map writes")。4bm28資訊網——每日最新資訊28at.com

03 、總結

本文介紹 Go 語言為什么不支持并發讀寫 map,Go 官方的說法是在多數情況下 map 只存在并發讀操作,如果原生支持并發讀寫,即降低了并發讀操作的性能。4bm28資訊網——每日最新資訊28at.com

通過閱讀源碼,我們了解到在運行時檢測是否存在其它 goroutine 對 map 的寫操作,如果存在,則返回致命錯誤。4bm28資訊網——每日最新資訊28at.com

讀者朋友們在使用 map 時,要特別注意是否存在對 map 的并發寫操作,如果存在,要結合 sync 包的互斥鎖一起使用。4bm28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-55073-0.htmlGo 語言為什么不支持并發讀寫 map?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 大模型應用設計與實現指南,你學會了嗎?

下一篇: JetBrains 發布 2023 年 C# 開發者主要趨勢

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 岑巩县| 绍兴县| 莒南县| 肃北| 尼木县| 于都县| 乌兰县| 库伦旗| 阳高县| 浮山县| 清涧县| 荆门市| 临汾市| 鹤庆县| 临澧县| 攀枝花市| 白城市| 桑植县| 三门县| 上林县| 开远市| 天镇县| 鹿泉市| 和龙市| 封丘县| 万州区| 西昌市| 望谟县| 岳池县| 韶山市| 正安县| 衡山县| 利辛县| 朝阳县| 和平区| 昭通市| 伊川县| 杭锦后旗| 桃源县| 东海县| 江门市|