GoLang切片并發(fā)安全解決方案詳解_第1頁(yè)
GoLang切片并發(fā)安全解決方案詳解_第2頁(yè)
GoLang切片并發(fā)安全解決方案詳解_第3頁(yè)
GoLang切片并發(fā)安全解決方案詳解_第4頁(yè)
GoLang切片并發(fā)安全解決方案詳解_第5頁(yè)
已閱讀5頁(yè),還剩5頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第GoLang切片并發(fā)安全解決方案詳解目錄1.介紹切片并發(fā)問(wèn)題2.實(shí)踐檢驗(yàn)真理3.回答切片并發(fā)安全問(wèn)題4.解決切片并發(fā)安全問(wèn)題方式5.附

1.介紹切片并發(fā)問(wèn)題

關(guān)于切片的,Go語(yǔ)言中的切片原生支持并發(fā)嗎?

2.實(shí)踐檢驗(yàn)真理

實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn),所以當(dāng)我們遇到一個(gè)不確定的問(wèn)題,直接寫(xiě)demo來(lái)驗(yàn)證,因?yàn)榍衅奶攸c(diǎn),我們可以分多種情況來(lái)驗(yàn)證

1.不指定索引,動(dòng)態(tài)擴(kuò)容并發(fā)向切片添加數(shù)據(jù)

2.指定索引,指定容量并發(fā)向切片添加數(shù)據(jù)

不指定索引,動(dòng)態(tài)擴(kuò)容并發(fā)向切片添加數(shù)據(jù)

不指定索引,動(dòng)態(tài)擴(kuò)容并發(fā)向切片添加數(shù)據(jù):

通過(guò)打印數(shù)據(jù)發(fā)現(xiàn)每次len與cap的結(jié)果都不一致

funcconcurrentAppendSliceNotForceIndex(){

sl:=make([]int,0)

wg:=sync.WaitGroup{}

forindex:=0;index100;index++{

k:=index

wg.Add(1)

gofunc(numint){

sl=append(sl,num)

wg.Done()

}(k)

wg.Wait()

fmt.Println(sl)

fmt.Printf("finallen(sl)=%dcap(sl)=%d\n",len(sl),cap(sl))

funcmain(){

concurrentAppendSliceNotForceIndex()

/*第一次運(yùn)行代碼后,輸出:[2015678910417111213141516211819202322242526392728293031355554565758596061626463656667686970717273747576777879808182838486919293949695979899]

finallen(sl)=74cap(sl)=128*/

//第二次運(yùn)行代碼后,輸出:省略切片元素輸出...finallen(sl)=81cap(sl)=128

//第二次運(yùn)行代碼后,輸出:省略切片元素輸出...finallen(sl)=77cap(sl)=128

}

指定索引,指定容量并發(fā)向切片添加數(shù)據(jù)

指定索引,指定容量并發(fā)向切片添加數(shù)據(jù):

通過(guò)結(jié)果我們可以發(fā)現(xiàn)符合我們的預(yù)期,長(zhǎng)度和容量都是100

funcconcurrentAppendSliceForceIndex(){

sl:=make([]int,100)

wg:=sync.WaitGroup{}

forindex:=0;index100;index++{

k:=index

wg.Add(1)

gofunc(numint){

sl[num]=num

wg.Done()

}(k)

wg.Wait()

fmt.Println(sl)

fmt.Printf("finallen(sl)=%dcap(sl)=%d\n",len(sl),cap(sl))

funcmain(){

concurrentAppendSliceForceIndex()

/*第一次運(yùn)行代碼后,輸出:[01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787

98081828384858687888990919293949596979899]

finallen(sl)=100cap(sl)=100*/

/*第一次運(yùn)行代碼后,輸出:[01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787

98081828384858687888990919293949596979899]

finallen(sl)=100cap(sl)=100*/

/*第一次運(yùn)行代碼后,輸出:[01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787

98081828384858687888990919293949596979899]

finallen(sl)=100cap(sl)=100*/

3.回答切片并發(fā)安全問(wèn)題

我們都知道切片是對(duì)數(shù)組的抽象,其底層就是數(shù)組,在并發(fā)下寫(xiě)數(shù)據(jù)到相同的索引位會(huì)被覆蓋,并且切片也有自動(dòng)擴(kuò)容的功能,當(dāng)切片要進(jìn)行擴(kuò)容時(shí),就要替換底層的數(shù)組,在切換底層數(shù)組時(shí),多個(gè)goroutine是同時(shí)運(yùn)行的,哪個(gè)goroutine先運(yùn)行是不確定的,不論哪個(gè)goroutine先寫(xiě)入內(nèi)存,肯定就有一次寫(xiě)入會(huì)覆蓋之前的寫(xiě)入,所以在動(dòng)態(tài)擴(kuò)容時(shí)并發(fā)寫(xiě)入數(shù)組是不安全的;

所以當(dāng)別人問(wèn)你slice支持并發(fā)時(shí),你就可以這樣回答它:

當(dāng)指定索引使用切片時(shí),切片是支持并發(fā)讀寫(xiě)索引區(qū)的數(shù)據(jù)的,但是索引區(qū)的數(shù)據(jù)在并發(fā)時(shí)會(huì)被覆蓋的;當(dāng)不指定索引切片時(shí),并且切片動(dòng)態(tài)擴(kuò)容時(shí),并發(fā)場(chǎng)景下擴(kuò)容會(huì)被覆蓋,所以切片是不支持并發(fā)的~。

4.解決切片并發(fā)安全問(wèn)題方式

針對(duì)上述問(wèn)題,我們可以多種方法來(lái)解決切片并發(fā)安全的問(wèn)題:

1.加互斥鎖

2.使用channel串行化操作

3.使用sync.map代替切片

5.附

設(shè)置為1的的時(shí)候,runtime.GOMAXPROCS(1)

packagemain

import(

"fmt"

"runtime"

"sync"

funcconcurrentAppendSliceNotForceIndex(){

sl:=make([]int,0)

wg:=sync.WaitGroup{}

forindex:=0;index100;index++{

k:=index

wg.Add(1)

gofunc(numint){

sl=append(sl,num)

wg.Done()

}(k)

wg.Wait()

fmt.Println(sl)

fmt.Printf("finallen(sl)=%dcap(sl)=%d\n",len(sl),cap(sl))

funcmain(){

runtime.GOMAXPROCS(1)

concurrentAppendSliceNotForceIndex()

[99012345678910111213141516171819202122232425262728

29303132333435363738394041424344454647484950515253545

55657585960616263646566676869707172737475767778798081

8283848586878889909192939495969798]

finallen(sl)=100cap(sl)=128

[13012345678910111299141516171819202122232425262728

29303132333435363738394041424344454647484950515253545

55657585960616263646566676869707172737475767778798081

8283848586878889909192939495969798]

finallen(sl)=100cap(sl)=128

[10012345678999111213141516171819202122232425262728

29303132333435363738394041424344454647484950515253545

55657585960616263646566676869707172737475767778798081

8283848586878889909192939495969798]

finallen(sl)=100cap(sl)=128

packagemain

import(

"fmt"

"runtime"

"sync"

varwgsync.WaitGroup

varsl[]int

funcadd(){

forindex:=0;index100;index++{

sl=append(sl,index)

wg.Done()

funcmain(){

runtime.GOMAXPROCS(1)

wg.Add(1)

goadd()

wg.Wait()

//無(wú)論執(zhí)行多少次都輸出一下結(jié)果

fmt.Println(sl)

fmt.Printf("finallen(sl)=%dcap(sl)=%d\n",len(sl),cap(sl))

[012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626

3646566676869707172737475767778798081828384858687888990919293949596979899]

finallen(sl)=100cap(sl)=128

}

packagemain

import(

"fmt"

"runtime"

"sync"

varwgsync.WaitGroup

varsl[]int

funcadd(){

forindex:=0;indexindex++{

sl=append(sl,index)

wg.Done()

funcmain(){

runtime.GOMAXPROCS(1)

wg.Add(2)

goadd()

goadd()

wg.Wait()

//無(wú)論執(zhí)行多少次都輸出一下結(jié)果

fmt.Println(sl)

fmt.Printf("finallen(sl)=%dcap(sl)=%d\n",len(sl),cap(sl))

[012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849012345678910111213141516

171819202122232425262728293031323334353637383940414243444546474849]

finallen(sl)=100cap(sl)=128

}

不限數(shù)量:

packagemain

import(

"fmt"

"sync"

varwgsync.WaitGroup

varsl[]int

funcadd(){

forindex:=0;indexindex++{

sl=append(sl,index)

wg.Done()

funcmain(){

wg.Add(2)

goadd()

goadd()

wg.Wait()

fmt.Println(sl)

fmt.Printf("finallen(sl)=%dcap(sl)=%d\n",len(sl),cap(sl))

[012345678910111213141516171819202122232425262728293031012345678910111213141516171819202122232425262728293031323334

353637383940414243444546474849]

finallen(sl)=82cap(sl)=128

}

加鎖

packagemain

import(

"fmt"

"sync"

varwgsync.WaitGroup

varsl[]int

varlocksync.Mutex

funcadd(){

forindex:=0;indexindex++{

lock.Lock()

sl=append(sl,index)

lock.Unlock()

wg.Done()

funcmain(){

wg.Add(2)

goadd()

goa

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論