2 回答

TA貢獻2039條經驗 獲得超8個贊
對所見的解釋:
在 Go Playground 上,GOMAXPROCS是1( proof )。
這意味著一次執行一個 goroutine,如果該 goroutine 沒有阻塞,則調度程序不會被迫切換到其他 goroutine。
你的代碼(就像每個 Go 應用程序一樣)從一個執行main()函數的 goroutine(主 goroutine)開始。它啟動另一個執行該other()函數的goroutine ,然后它從done通道接收- 阻塞。所以調度器必須切換到另一個 goroutine(執行other()函數)。
在你的other()函數中,當你在done通道上發送一個值時,這使得當前 ( other()) 和maingoroutine 都可以運行。調度程序選擇繼續運行other(),因為GOMAXPROCS=1,main()不繼續。現在other()啟動另一個執行無限循環的 goroutine。調度器選擇執行這個 goroutine,它需要很長時間才能進入阻塞狀態,因此main()不會繼續。
然后 Go Playground 沙箱的超時是一種赦免:
過程耗時太長
請注意,Go Memory Model僅保證某些事件在其他事件之前發生,您無法保證 2 個并發 goroutine 是如何執行的。這使得輸出不確定。
您不得質疑任何不違反 Go Memory Model 的執行順序。如果您希望執行到達代碼中的某些點(以執行某些語句),則需要顯式同步(您需要同步 goroutine)。
另請注意,Go Playground 上的輸出是緩存的,因此如果您再次運行該應用程序,它將不會再次運行,而是會立即顯示緩存的輸出。如果您更改代碼中的任何內容(例如插入空格或注釋),然后再次運行它,它將被編譯并再次運行。您會通過增加的響應時間注意到這一點。使用當前版本(Go 1.6),您每次都會看到相同的輸出。
在本地運行(在您的機器上):
當您在本地運行它時,很可能GOMAXPROCS會大于1它默認的可用 CPU 內核數(自 Go 1.5 起)。因此,如果您有一個執行無限循環的 goroutine 無關緊要,另一個 goroutine 將同時執行,即main(),當main()返回時,您的程序終止;它不會等待其他非maingoroutine 完成(參見規范:程序執行)。
另請注意,即使您設置GOMAXPROCS為1,您的應用程序也很可能會在“短”時間內退出,因為調度程序實現將切換到其他 goroutines 而不僅僅是永遠執行無限循環(但是,如上所述,這是不確定的)。當它發生時,它將是main()goroutine,因此當main()完成并返回時,您的應用程序將終止。
在 Go Playground 上玩你的應用:
如前所述,默認情況下GOMAXPROCS是1在 Go Playground 上。但是允許將其設置為更高的值,例如:
runtime.GOMAXPROCS(2)
如果沒有顯式同步,執行仍然是不確定的,但是您將觀察到不同的執行順序和終止,而不會遇到超時:
Hello, playground
Here
Here
Here
...
<Here is printed 996 times, then:>
Finished.
在Go Playground上試試這個變體。

TA貢獻1995條經驗 獲得超2個贊
您將在屏幕上看到的內容是不確定的。或者更準確地說,如果true
您傳遞給頻道的值有任何機會被延遲,您會看到一些“此處”。
但通常 Stdout 是緩沖的,這意味著它不會立即打印,但數據會累積,并在達到最大緩沖區大小后打印。在您的情況下,在打印“此處”之前,主要功能已經完成,因此過程完成。
經驗法則是:main 函數必須是存活的,否則所有其他 goroutine 都會被殺死。
- 2 回答
- 0 關注
- 173 瀏覽
添加回答
舉報