中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

golang中的并發等于并行嗎

發布時間:2020-06-16 14:35:18 來源:億速云 閱讀:197 作者:鴿子 欄目:編程語言

并發不等于并行

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并發不是并行的詳細內容,更多請關注億速云其它相關文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

慈溪市| 宁河县| 陆川县| 酒泉市| 密山市| 许昌县| 福安市| 宿松县| 台安县| 蒙自县| 汝阳县| 手机| 兴宁市| 高雄市| 宜兴市| 武清区| 舞阳县| 邯郸县| 永吉县| 江津市| 兴海县| 大厂| 忻州市| 沭阳县| 辽宁省| 土默特右旗| 西乌| 黄陵县| 云浮市| 平南县| 桓台县| 蕲春县| 岳西县| 巴青县| 怀集县| 卢湾区| 布尔津县| 伊川县| 紫阳县| 同江市| 恩平市|