国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

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

這篇具有很好參考價值的文章主要介紹了Go 語言為什么不支持并發(fā)讀寫 map?。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

大家好,我是 frank ,「 Golang 語言開發(fā)?!构娞栕髡?。

01 介紹

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

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

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

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

在需要并發(fā)讀寫操作 map 時,可以結(jié)合 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)
}

輸出結(jié)果:

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 結(jié)構(gòu)體中的字段 flags,該字段用于標(biāo)記 map 是否為寫入狀態(tài)。

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

03 總結(jié)

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

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

讀者朋友們在使用 map 時,要特別注意是否存在對 map 的并發(fā)寫操作,如果存在,要結(jié)合 sync 包的互斥鎖一起使用。文章來源地址http://www.zghlxwxcb.cn/news/detail-786520.html

到了這里,關(guān)于Go 語言為什么不支持并發(fā)讀寫 map?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【Golang】三分鐘讓你快速了解Go語言&為什么我們需要Go語言?

    【Golang】三分鐘讓你快速了解Go語言&為什么我們需要Go語言?

    博主簡介: 努力學(xué)習(xí)的大一在校計算機(jī)專業(yè)學(xué)生,熱愛學(xué)習(xí)和創(chuàng)作。目前在學(xué)習(xí)和分享:數(shù)據(jù)結(jié)構(gòu)、Go,Java等相關(guān)知識。 博主主頁: @是瑤瑤子啦 所屬專欄: Go語言核心編程 近期目標(biāo): 寫好專欄的每一篇文章 Go 語言從 2009 年 9 月 21 日開始作為谷歌公司 20% 兼職項目,即相關(guān)

    2023年04月21日
    瀏覽(25)
  • Go 語言為什么建議多使用切片,少使用數(shù)組?

    大家好,我是 frank,「Golang 語言開發(fā)?!构娞栕髡?。 01 介紹 在 Go 語言中,數(shù)組固定長度,切片可變長度;數(shù)組和切片都是值傳遞,因為切片傳遞的是指針,所以切片也被稱為“引用傳遞”。 讀者朋友們在使用 Go 語言開發(fā)項目時,或者在閱讀 Go 開源項目源碼時,發(fā)現(xiàn)很少

    2024年02月03日
    瀏覽(31)
  • 為什么說 Go 語言字符串是不可變的?

    原文鏈接: 為什么說 Go 語言字符串是不可變的? 最近有讀者留言說,平時在寫代碼的過程中,是會對字符串進(jìn)行修改的,但網(wǎng)上都說 Go 語言字符串是不可變的,這是為什么呢? 這個問題本身并不困難,但對于新手來說確實容易產(chǎn)生困惑,今天就來回答一下。 首先來看看它

    2024年02月07日
    瀏覽(18)
  • 【Golang】一篇文章帶你快速了解Go語言&為什么你要學(xué)習(xí)Go語言

    【Golang】一篇文章帶你快速了解Go語言&為什么你要學(xué)習(xí)Go語言

    目錄 1. 為什么互聯(lián)網(wǎng)世界需要Go語言 1.1 硬件限制:摩爾定律已然失效? 1.2 Go語言為并發(fā)而生 1.3 Go性能強(qiáng)悍 1.4 Go語言簡單易學(xué) 1.4.1 語法簡潔 1.4.2 代碼風(fēng)格統(tǒng)一 1.4.3開發(fā)效率高? 2.Go語言的誕生與發(fā)展 2.1什么是Go語言? ?2.2 Go語言的誕生 2.3?Go Gopher——Go語言的吉祥物 3. 為什么

    2024年02月04日
    瀏覽(35)
  • 是時候回答【我為什么要學(xué)習(xí) Go 語言(golang)】這個問題了

    想必每個人在學(xué)習(xí)新事物之前,都會捫心自問:“我為什么要學(xué)習(xí)它呢?” 正如我們讀 四大名著 一般,也只有在您讀過了 四大名著 后,再細(xì)看中國幾千年歷史不就是 天下大勢合久必分,分久必合 ,再者,便是與友數(shù)人相聚,席間您述說您通勤時所遇到有意思的事了,而您

    2023年04月09日
    瀏覽(18)
  • 《Go語言在微服務(wù)中的崛起:為什么Go是下一個后端之星?》

    《Go語言在微服務(wù)中的崛起:為什么Go是下一個后端之星?》

    ???? 博主貓頭虎???? 帶您進(jìn)入 Golang 語言的新世界???? ?? 博客首頁 ——????貓頭虎的博客?? ?? 《面試題大全專欄》 ?? 文章圖文并茂??生動形象??簡單易學(xué)!歡迎大家來踩踩~?? ?? 《IDEA開發(fā)秘籍專欄》 ?? 學(xué)會IDEA常用操作,工作效率翻倍~?? ?? 《100天精通

    2024年02月09日
    瀏覽(35)
  • 【Golang】Golang進(jìn)階系列教程--為什么 Go 語言 struct 要使用 tags

    【Golang】Golang進(jìn)階系列教程--為什么 Go 語言 struct 要使用 tags

    在 Go 語言中,struct 是一種常見的數(shù)據(jù)類型,它可以用來表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。在 struct 中,我們可以定義多個字段,每個字段可以有不同的類型和名稱。 除了這些基本信息之外,Go 還提供了 struct tags,它可以用來指定 struct 中每個字段的元信息。 在本文中,我們將探討為什

    2024年02月15日
    瀏覽(38)
  • 【Golang】Golang進(jìn)階系列教程--為什么說 Go 語言字符串是不可變的?

    【Golang】Golang進(jìn)階系列教程--為什么說 Go 語言字符串是不可變的?

    最近有讀者留言說,平時在寫代碼的過程中,是會對字符串進(jìn)行修改的,但網(wǎng)上都說 Go 語言字符串是不可變的,這是為什么呢? 這個問題本身并不困難,但對于新手來說確實容易產(chǎn)生困惑,今天就來回答一下。 首先來看看它的底層結(jié)構(gòu): 和切片的結(jié)構(gòu)很像,只不過少了一個

    2024年02月14日
    瀏覽(95)
  • 【設(shè)計模式與范式:行為型】69 | 訪問者模式(下):為什么支持雙分派的語言不需要訪問者模式?

    上一節(jié)課中,我們學(xué)習(xí)了訪問者模式的原理和實現(xiàn),并且還原了訪問者模式誕生的思維過程。總體上來講,這個模式的代碼實現(xiàn)比較難,所以應(yīng)用場景并不多。從應(yīng)用開發(fā)的角度來說,它的確不是我們學(xué)習(xí)的重點。 不過,我們前面反復(fù)說過,學(xué)習(xí)我的專欄,并不只是讓你掌握

    2024年02月10日
    瀏覽(23)
  • 既然有Map了,為什么還要有Redis?

    既然有Map了,為什么還要有Redis?

    以下內(nèi)容轉(zhuǎn)自掘金 作者:哪吒編程 Redis可以存儲幾十個G的數(shù)據(jù),Map行嗎? Redis的緩存可以進(jìn)行本地持久化,Map行嗎? Redis可以作為分布式緩存,Map只能在同一個JVM中進(jìn)行緩存; Redis支持每秒百萬級的并發(fā),Map行嗎? Redis有過期機(jī)制,Map有嗎? Redis有豐富的API,支持非常多的應(yīng)

    2024年02月03日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包