最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
golang中的并發(fā)等于并行嗎

并發(fā)不等于并行

創(chuàng)新互聯(lián)公司主要從事做網(wǎng)站、成都網(wǎng)站制作、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)臺江,十載網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18982081108

golang的核心開發(fā)人員Rob Pike專門提到了這個話題

雖然我們在for循環(huán)中使用了go 創(chuàng)建了一個goroutine,我們想當(dāng)然會認(rèn)為,每次循環(huán)變量時,golang一定會執(zhí)行這個goroutine,然后輸出當(dāng)時的變量。

這時,我們就陷入了思維定勢。 默認(rèn)并發(fā)等于并行。

誠然,通過go創(chuàng)建的goroutine是會并發(fā)的執(zhí)行其中的函數(shù)代碼。

但一定會按照我們所設(shè)想的那樣每次循環(huán)時執(zhí)行嗎?

答案是否定的!

Rob Pike專門提到了golang中并發(fā)指的是代碼結(jié)構(gòu)中的某些函數(shù)邏輯上可以同時運行,但物理上未必會同時運行。而并行則指的就是在物理層面也就是使用了不同CPU在執(zhí)行不同或者相同的任務(wù)。

golang的goroutine調(diào)度模型決定了,每個goroutine是運行在虛擬CPU中的(也就是我們通過runtime.GOMAXPROCS(1)所設(shè)定的虛擬CPU個數(shù))。

虛擬CPU個數(shù)未必會和實際CPU個數(shù)相吻合。每個goroutine都會被一個特定的P(虛擬CPU)選定維護(hù),而M(物理計算資源)每次回挑選一個有效P,然后執(zhí)行P中的goroutine。

每個P會將自己所維護(hù)的goroutine放到一個G隊列中,其中就包括了goroutine堆棧信息,是否可執(zhí)行信息等等。默認(rèn)情況下,P的數(shù)量與實際物理CPU的數(shù)量相等。

因此當(dāng)我們通過循環(huán)來創(chuàng)建goroutine時,每個goroutine會被分配到不同的P隊列中。而M的數(shù)量又不是唯一的,當(dāng)M隨機(jī)挑選P時,也就等同隨機(jī)挑選了goroutine。

在本題中,我們設(shè)定了P=1。所以所有的goroutine會被綁定到同一個P中。 如果我們修改runtime.GOMAXPROCS的值,就會看到另外的順序。 如果我們輸出goroutine id,就可以看到隨機(jī)挑選的效果:

func main() {
wg := sync.WaitGroup{}
wg.Add(20)
for i := 0; i < 10; i++ {
go func() {
var buf [64]byte
n := runtime.Stack(buf[:], false)
idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0]
id, err := strconv.Atoi(idField)
if err != nil {
panic(fmt.Sprintf("cannot get goroutine id: %v", err))
}
fmt.Println("go routine 1 i: ", i, id)
wg.Done()
}()
}
for i := 0; i < 10; i++ {
go func(i int) {
var buf [64]byte
n := runtime.Stack(buf[:], false)
idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0]
id, err := strconv.Atoi(idField)
if err != nil {
panic(fmt.Sprintf("cannot get goroutine id: %v", err))
}
fmt.Println("go routine 2 i: ", i, id)
wg.Done()
}(i)

}
wg.Wait()
}

輸出如下:

go routine 2 i: 9 24
go routine 1 i: 10 11
go routine 1 i: 10 5
go routine 1 i: 10 6
go routine 2 i: 3 18
go routine 1 i: 10 9
go routine 1 i: 10 10
go routine 1 i: 10 8
go routine 2 i: 0 15
go routine 2 i: 4 19
go routine 2 i: 6 21
go routine 1 i: 10 7
go routine 1 i: 10 14
go routine 2 i: 7 22
go routine 2 i: 8 23
go routine 1 i: 10 13
go routine 2 i: 5 20
go routine 1 i: 10 12
go routine 2 i: 1 16
go routine 2 i: 2 17
?> ~/S/g/g/s/t/C/goroutine ./goroutine
go routine 1 i: 10 11
go routine 2 i: 9 24
go routine 1 i: 10 6
go routine 1 i: 10 14
go routine 1 i: 10 9
go routine 1 i: 10 10
go routine 1 i: 10 12
go routine 2 i: 0 15
go routine 1 i: 10 13
go routine 1 i: 10 5
go routine 2 i: 1 16
go routine 2 i: 5 20
go routine 1 i: 10 7
go routine 2 i: 7 22
go routine 2 i: 3 18
go routine 2 i: 2 17
go routine 2 i: 4 19
go routine 1 i: 10 8
go routine 2 i: 8 23
go routine 2 i: 6 21

我們再回到這道題中,雖然在循環(huán)中通過go定義了一個goroutine。但我們說到了,并發(fā)不等于并行。因此雖然定義了,但此刻不見得就會去執(zhí)行。

需要等待M選擇P之后,才能去執(zhí)行g(shù)oroutine。 關(guān)于golang中g(shù)oroutine是如何進(jìn)行調(diào)度的(GPM模型),可以參考Scalable Go Scheduler Design Doc或者LearnConcurrency

以上就是golang并發(fā)不是并行的詳細(xì)內(nèi)容,更多請關(guān)注創(chuàng)新互聯(lián)其它相關(guān)文章!


網(wǎng)頁標(biāo)題:golang中的并發(fā)等于并行嗎
分享鏈接:http://fisionsoft.com.cn/article/jocdce.html