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

當(dāng)前位置:首頁(yè) > 科技  > 軟件

Go 語(yǔ)言為什么不支持并發(fā)讀寫(xiě) map?

來(lái)源: 責(zé)編: 時(shí)間:2024-01-02 09:29:55 214觀看
導(dǎo)讀01 、介紹在 Go 語(yǔ)言項(xiàng)目開(kāi)發(fā)中,我們經(jīng)常會(huì)使用哈希表 map,它的時(shí)間復(fù)雜度是 O(1),Go 語(yǔ)言中的 map 使用開(kāi)放尋址法避免哈希碰撞。Go 語(yǔ)言中的 map 并非原子操作,不支持并發(fā)讀寫(xiě)操作。Go 官方認(rèn)為 map 在大多數(shù)情況下是使

01 、介紹

在 Go 語(yǔ)言項(xiàng)目開(kāi)發(fā)中,我們經(jīng)常會(huì)使用哈希表 map,它的時(shí)間復(fù)雜度是 O(1),Go 語(yǔ)言中的 map 使用開(kāi)放尋址法避免哈希碰撞。9ZP28資訊網(wǎng)——每日最新資訊28at.com

Go 語(yǔ)言中的 map 并非原子操作,不支持并發(fā)讀寫(xiě)操作。9ZP28資訊網(wǎng)——每日最新資訊28at.com

Go 官方認(rèn)為 map 在大多數(shù)情況下是使用 map 進(jìn)行并發(fā)讀操作,僅在少數(shù)情況下是使用 map 進(jìn)行并發(fā)讀寫(xiě)操作。9ZP28資訊網(wǎng)——每日最新資訊28at.com

如果 Go 語(yǔ)言中的 map 原生支持并發(fā)讀寫(xiě)操作,在操作時(shí)需要先獲取互斥鎖,反而會(huì)降低只有并發(fā)讀操作時(shí)的性能。9ZP28資訊網(wǎng)——每日最新資訊28at.com

在需要并發(fā)讀寫(xiě)操作 map 時(shí),可以結(jié)合 sync 包中的互斥鎖一起使用。9ZP28資訊網(wǎng)——每日最新資訊28at.com

02 、并發(fā)讀寫(xiě) map

Go 支持并發(fā)讀 map,不支持并發(fā)讀寫(xiě) map。9ZP28資訊網(wǎng)——每日最新資訊28at.com

示例代碼:9ZP28資訊網(wǎng)——每日最新資訊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)}

輸出結(jié)果:9ZP28資訊網(wǎng)——每日最新資訊28at.com

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

閱讀上面這段代碼,我們并發(fā)讀寫(xiě) map 類型的變量 m,在運(yùn)行時(shí),返回致命錯(cuò)誤 fatal error: concurrent map read and map write。9ZP28資訊網(wǎng)——每日最新資訊28at.com

Go 語(yǔ)言中的 map 在運(yùn)行時(shí)是怎么檢測(cè)到 map 的存在寫(xiě)操作?9ZP28資訊網(wǎng)——每日最新資訊28at.com

源碼:9ZP28資訊網(wǎng)——每日最新資訊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}

閱讀上面這段源碼,我們可以發(fā)現(xiàn)在 hmap 結(jié)構(gòu)體中的字段 flags,該字段用于標(biāo)記 map 是否為寫(xiě)入狀態(tài)。9ZP28資訊網(wǎng)——每日最新資訊28at.com

在訪問(wèn) map 時(shí),通過(guò)判斷 hmap.flags 和 hashWriting 的值,可知是否有其它 goroutine 訪問(wèn) map,如果有,則返回致命錯(cuò)誤 fatal("concurrent map writes")。9ZP28資訊網(wǎng)——每日最新資訊28at.com

03 、總結(jié)

本文介紹 Go 語(yǔ)言為什么不支持并發(fā)讀寫(xiě) map,Go 官方的說(shuō)法是在多數(shù)情況下 map 只存在并發(fā)讀操作,如果原生支持并發(fā)讀寫(xiě),即降低了并發(fā)讀操作的性能。9ZP28資訊網(wǎng)——每日最新資訊28at.com

通過(guò)閱讀源碼,我們了解到在運(yùn)行時(shí)檢測(cè)是否存在其它 goroutine 對(duì) map 的寫(xiě)操作,如果存在,則返回致命錯(cuò)誤。9ZP28資訊網(wǎng)——每日最新資訊28at.com

讀者朋友們?cè)谑褂?nbsp;map 時(shí),要特別注意是否存在對(duì) map 的并發(fā)寫(xiě)操作,如果存在,要結(jié)合 sync 包的互斥鎖一起使用。9ZP28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-55047-0.htmlGo 語(yǔ)言為什么不支持并發(fā)讀寫(xiě) map?

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 大模型應(yīng)用設(shè)計(jì)與實(shí)現(xiàn)指南,你學(xué)會(huì)了嗎?

下一篇: Kubernetes CRD & Operator 簡(jiǎn)介

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 佛坪县| 郴州市| 怀集县| 南昌县| 东辽县| 唐河县| 卢湾区| 华容县| 虎林市| 曲阳县| 亚东县| 安陆市| 青州市| 武安市| 明溪县| 玛曲县| 呼和浩特市| 贺州市| 阿克陶县| 开封县| 工布江达县| 扬州市| 广丰县| 上杭县| 衡水市| 沭阳县| 清苑县| 江华| 奉贤区| 鄂尔多斯市| 永年县| 红安县| 五台县| 广平县| 蕉岭县| 肇东市| 连南| 巴彦淖尔市| 石屏县| 密山市| 大邑县|