免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

golang中的并發等于并行嗎

并發不等于并行

創新互聯公司主要從事做網站、成都網站制作、網頁設計、企業做網站、公司建網站等業務。立足成都服務臺江,十載網站建設經驗,價格優惠、服務專業,歡迎來電咨詢建站服務:18982081108

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

雖然我們在for循環中使用了go 創建了一個goroutine,我們想當然會認為,每次循環變量時,golang一定會執行這個goroutine,然后輸出當時的變量。

這時,我們就陷入了思維定勢。 默認并發等于并行。

誠然,通過go創建的goroutine是會并發的執行其中的函數代碼。

但一定會按照我們所設想的那樣每次循環時執行嗎?

答案是否定的!

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

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

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

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

因此當我們通過循環來創建goroutine時,每個goroutine會被分配到不同的P隊列中。而M的數量又不是唯一的,當M隨機挑選P時,也就等同隨機挑選了goroutine。

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

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

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

需要等待M選擇P之后,才能去執行goroutine。 關于golang中goroutine是如何進行調度的(GPM模型),可以參考Scalable Go Scheduler Design Doc或者LearnConcurrency

以上就是golang并發不是并行的詳細內容,更多請關注創新互聯其它相關文章!

當前題目:golang中的并發等于并行嗎
文章URL:http://m.newbst.com/article24/jocdce.html

成都網站建設公司_創新互聯,為您提供網站設計網站收錄商城網站小程序開發品牌網站設計Google

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

小程序開發