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

Golang 中的 slice 為什么是并發(fā)不安全的?

這篇具有很好參考價(jià)值的文章主要介紹了Golang 中的 slice 為什么是并發(fā)不安全的?。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

Golang 中的 slice 為什么是并發(fā)不安全的?

一、并發(fā)不安全的

??在Go語(yǔ)言中,slice是并發(fā)不安全的,主要有以下兩個(gè)原因:數(shù)據(jù)競(jìng)爭(zhēng)、內(nèi)存重分配。

??數(shù)據(jù)競(jìng)爭(zhēng):slice底層的結(jié)構(gòu)體包含一個(gè)指向底層數(shù)組的指針和該數(shù)組的長(zhǎng)度,當(dāng)多個(gè)協(xié)程并發(fā)訪(fǎng)問(wèn)同一個(gè)slice時(shí),有可能會(huì)出現(xiàn)數(shù)據(jù)競(jìng)爭(zhēng)的問(wèn)題。例如,一個(gè)協(xié)程在修改slice的長(zhǎng)度,而另一個(gè)協(xié)程同時(shí)在讀取或修改slice的內(nèi)容。

??內(nèi)存重分配:在向slice中追加元素時(shí),可能會(huì)觸發(fā)slice的擴(kuò)容操作,在這個(gè)過(guò)程中,如果有其他協(xié)程訪(fǎng)問(wèn)了slice,就會(huì)導(dǎo)致指向底層數(shù)組的指針出現(xiàn)異常。

二、并發(fā)場(chǎng)景

??多個(gè)協(xié)程同時(shí)向 slice 追加元素,會(huì)有一部分元素被追加到了舊的底層數(shù)組里,最終 slice 的長(zhǎng)度小于目標(biāo)值。

func main() {
	a := make([]int, 0)
	for i := 0; i < 10000; i++ {
		go func(i int) {
			a = append(a, i)
		}(i)
	}
	fmt.Println(len(a)) // 9015 < 10000
}

golang slice 并發(fā)安全,golang,golang,數(shù)據(jù)結(jié)構(gòu)

三、實(shí)現(xiàn) slice 并發(fā)安全

??要實(shí)現(xiàn) slice 并發(fā)安全,有兩種方法:加互斥鎖、使用channel串行化操作。

方式一:使用互斥鎖 sync.Mutex

??追加元素之前調(diào)用 Lock() 函數(shù)加鎖,追加完后,調(diào)用 Unlock() 解鎖。

func main() {
	var lock sync.Mutex //互斥鎖
	a := make([]int, 0)
	var wg sync.WaitGroup
	for i := 0; i < 10000; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			lock.Lock()
			defer lock.Unlock()
			a = append(a, i)
		}(i)
	}
	wg.Wait()
	fmt.Println(len(a))
	// equal 10000
}

最終 slice 的長(zhǎng)度等于目標(biāo)值。

golang slice 并發(fā)安全,golang,golang,數(shù)據(jù)結(jié)構(gòu)

方式二:使用channel串行化操作

??生產(chǎn)者生產(chǎn)元素,發(fā)送到通道中,消費(fèi)者從通道中接收元素,追加到 slice 中。使用無(wú)緩沖通道,接收方、發(fā)送方必須同時(shí)存在,負(fù)責(zé)任意一方都會(huì)阻塞。

func main() {
	buffer := make(chan int)
	a := make([]int, 0)
	// 消費(fèi)者
	go func() {
		for v := range buffer {
			a = append(a, v)
		}
	}()
	// 生產(chǎn)者
	var wg sync.WaitGroup
	for i := 0; i < 10000; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			buffer <- i
		}(i)
	}
	wg.Wait()
	fmt.Println(len(a))
	// equal 10000
}

最終 slice 的長(zhǎng)度等于目標(biāo)值。

golang slice 并發(fā)安全,golang,golang,數(shù)據(jù)結(jié)構(gòu)

兩種方式的比較

??加互斥鎖適合于對(duì)性能要求不高的場(chǎng)景,畢竟鎖的粒度太大,這種方式屬于通過(guò)共享內(nèi)存來(lái)實(shí)現(xiàn)通信。channle 適合于對(duì)性能要求大的場(chǎng)景,channle 就是專(zhuān)用于 goroutine 間通信的,這種方式屬于通過(guò)通信來(lái)實(shí)現(xiàn)共享內(nèi)存。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-753337.html

到了這里,關(guān)于Golang 中的 slice 為什么是并發(fā)不安全的?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 【Golang】Golang進(jìn)階系列教程--為什么 Go 不支持 []T 轉(zhuǎn)換為 []interface

    【Golang】Golang進(jìn)階系列教程--為什么 Go 不支持 []T 轉(zhuǎn)換為 []interface

    在 Go 中,如果 interface{} 作為函數(shù)參數(shù)的話(huà),是可以傳任意參數(shù)的,然后通過(guò)類(lèi)型斷言來(lái)轉(zhuǎn)換。 舉個(gè)例子: 不管是傳 int 還是 string,最終都能輸出正確結(jié)果。 那么,既然是這樣的話(huà),我就有一個(gè)疑問(wèn)了,拿出我舉一反三的能力。是否可以將 []T 轉(zhuǎn)換為 []interface 呢? 比如下面

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

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

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

    2024年02月14日
    瀏覽(98)
  • Golang對(duì)比Java、python為什么要保留指針

    平時(shí)我們?cè)贕olang使用指針一般是為了以下的情況: 方法直接修改原來(lái)對(duì)象 保證參數(shù)傳遞的自由,可以在傳遞重量級(jí)對(duì)象時(shí)使用指針 但Go 保留指針不僅僅是為了解決傳遞參數(shù)的問(wèn)題,還跟它的語(yǔ)言特性有密不可分的聯(lián)系。 Go 里面的變量是 值語(yǔ)義 ,這個(gè)跟 C/C++是一脈相承的。

    2024年01月17日
    瀏覽(31)
  • 【Golang】Golang進(jìn)階系列教程--為什么 Go for-range 的 value 值地址每次都一樣?

    循環(huán)語(yǔ)句是一種常用的控制結(jié)構(gòu),在 Go 語(yǔ)言中,除了 for 以外,還有一個(gè) range ,可以使用 for-range 循環(huán)迭代數(shù)組、切片、字符串、map 和 channel 這些數(shù)據(jù)類(lèi)型。 但是在使用 for-range 循環(huán)迭代數(shù)組和切片的時(shí)候,是很容易出錯(cuò)的,甚至很多老司機(jī)一不小心都會(huì)在這里

    2024年02月15日
    瀏覽(22)
  • 是時(shí)候回答【我為什么要學(xué)習(xí) Go 語(yǔ)言(golang)】這個(gè)問(wèn)題了

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

    2023年04月09日
    瀏覽(19)
  • 【Golang】三分鐘讓你快速了解Go語(yǔ)言&為什么我們需要Go語(yǔ)言?

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

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

    2023年04月21日
    瀏覽(29)
  • golang select兩個(gè)channel性能穩(wěn)定,三個(gè)channel時(shí)性能會(huì)發(fā)生抖動(dòng),為什么?

    golang select兩個(gè)channel性能穩(wěn)定,三個(gè)channel時(shí)性能會(huì)發(fā)生抖動(dòng),為什么? 答題思路 select — 讓 Goroutine 同時(shí)等待多個(gè) Channel 可讀或者可寫(xiě) — Goroutine — 調(diào)度器調(diào)度 — 資源競(jìng)爭(zhēng) — 不穩(wěn)定、抖動(dòng) 在 Go 中, select 語(yǔ)句用于在多個(gè)通道操作中進(jìn)行選擇 。當(dāng)有多個(gè)通道準(zhǔn)備好發(fā)送或接

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

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

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

    2024年02月04日
    瀏覽(37)
  • Golang 中的數(shù)組Array以及Slice底層實(shí)現(xiàn)

    Golang 中的數(shù)組Array以及Slice底層實(shí)現(xiàn)

    數(shù)組是指一系列同一類(lèi)型數(shù)據(jù)的集合。數(shù)組中包含的每個(gè)數(shù)據(jù)被稱(chēng)為數(shù)組元素 (element),這種類(lèi)型可以是任意的原始類(lèi)型,比如 int 、 string 等,也可以是用戶(hù)自定義的類(lèi)型。一個(gè)數(shù)組包含的元素個(gè)數(shù)被稱(chēng)為數(shù)組的長(zhǎng)度。 在 Golang 中數(shù)組是一個(gè)長(zhǎng)度固定的數(shù)據(jù)類(lèi)型, 數(shù)組的長(zhǎng)度

    2024年02月16日
    瀏覽(18)
  • golang并發(fā)安全-select

    golang并發(fā)安全-select

    前面說(shuō)了golang的channel,?今天我們看看golang select 是怎么實(shí)現(xiàn)的。 select 非默認(rèn)的case 中都是處理channel 的 接受和發(fā)送,所有scase 結(jié)構(gòu)體中c是用來(lái)存儲(chǔ)select 的case中使用的channel 編譯器在中間代碼生成期間會(huì)根據(jù) select 中 case 的不同對(duì)控制語(yǔ)句進(jìn)行優(yōu)化,這一過(guò)程都發(fā)生在cmd/c

    2024年01月23日
    瀏覽(16)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包