亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

goroutine 總是執行“后進先出”

goroutine 總是執行“后進先出”

Go
翻閱古今 2021-12-07 17:19:10
為了學習更多關于 Go 的知識,我一直在玩 goroutines,并且注意到了一些東西 - 但我不確定我看到了什么,希望有人能夠解釋以下行為。以下代碼完全符合您的期望:package mainimport (  "fmt")type Test struct {  me int}type Tests []Testfunc (test *Test) show() {  fmt.Println(test.me)}func main() {  var tests Tests  for i := 0; i < 10; i++ {    test := Test{      me: i,    }    tests = append(tests, test)  }  for _, test := range tests {    test.show()  }}并按順序打印 0 - 9?,F在,當代碼如下所示更改時,它總是首先返回最后一個 - 無論我使用哪個數字:package mainimport (    "fmt"    "sync")type Test struct {    me int}type Tests []Testfunc (test *Test) show(wg *sync.WaitGroup) {    fmt.Println(test.me)    wg.Done()}func main() {    var tests Tests    for i := 0; i < 10; i++ {        test := Test{            me: i,        }        tests = append(tests, test)    }    var wg sync.WaitGroup    wg.Add(10)    for _, test := range tests {        go func(t Test) {            t.show(&wg)        }(test)    }    wg.Wait()}這將返回:9 0 1 2 3 4 5 6 7 8循環的迭代順序沒有改變,所以我想這與 goroutines 有關系……基本上,我試圖理解為什么它的行為是這樣的……我知道 goroutines 可以在與它們產生的順序不同,但是,我的問題是為什么這總是這樣運行。好像有什么很明顯的東西我錯過了......
查看完整描述

2 回答

?
忽然笑

TA貢獻1806條經驗 獲得超5個贊

正如預期的那樣,輸出是偽隨機的,


package main


import (

    "fmt"

    "runtime"

    "sync"

)


type Test struct {

    me int

}


type Tests []Test


func (test *Test) show(wg *sync.WaitGroup) {

    fmt.Println(test.me)

    wg.Done()


}


func main() {

    fmt.Println("GOMAXPROCS", runtime.GOMAXPROCS(0))

    var tests Tests

    for i := 0; i < 10; i++ {

        test := Test{

            me: i,

        }

        tests = append(tests, test)

    }


    var wg sync.WaitGroup

    wg.Add(10)

    for _, test := range tests {

        go func(t Test) {

            t.show(&wg)

        }(test)

    }

    wg.Wait()


}

輸出:


$ go version

go version devel +af15bee Fri Jan 29 18:29:10 2016 +0000 linux/amd64

$ go run goroutine.go

GOMAXPROCS 4

9

4

5

6

7

8

1

2

3

0

$ go run goroutine.go

GOMAXPROCS 4

9

3

0

1

2

7

4

8

5

6

$ go run goroutine.go

GOMAXPROCS 4

1

9

6

8

4

3

0

5

7

2

你在圍棋操場上跑步嗎?Go Playground 在設計上是確定性的,這使得緩存程序更容易。


或者,您是否使用 runtime.GOMAXPROCS = 1 運行?這一次按順序運行一件事。這就是 Go 游樂場所做的。


查看完整回答
反對 回復 2021-12-07
?
瀟瀟雨雨

TA貢獻1833條經驗 獲得超4個贊

從 Go 1.5 開始,Go 例程是隨機安排的。所以,即使順序看起來一致,也不要依賴它

請參閱Go 1.5 發行說明:

在 Go 1.5 中,goroutine 的調度順序已經改變。調度程序的屬性從未由語言定義,但依賴于調度順序的程序可能會被這種更改破壞。我們已經看到一些(錯誤的)程序受到此更改的影響。如果您有隱式依賴調度順序的程序,則需要更新它們。

另一個潛在的重大變化是,運行時現在將同時運行的默認線程數(由 GOMAXPROCS 定義)設置為 CPU 上可用的內核數。在以前的版本中,默認值為 1。不希望以多核運行的程序可能會無意中中斷??梢酝ㄟ^刪除限制或明確設置 GOMAXPROCS 來更新它們。有關此更改的更詳細討論,請參閱設計文檔。


查看完整回答
反對 回復 2021-12-07
  • 2 回答
  • 0 關注
  • 253 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號