Go 知识点(01)— 主协程与子协程执行顺序
下面代碼的輸出結(jié)果是什么?
package mainimport ("fmt"
)func main() {for i := 0; i < 10; i++ {go func() {fmt.Println(i)}()}
}
運(yùn)行該代碼輸出的結(jié)果是什么? 可能有以下答案
- 大概率什么都沒有輸出
原因是: 只要主協(xié)程也就是 main 進(jìn)程執(zhí)行完畢,其它的 Go 協(xié)程就會立即結(jié)束,主協(xié)程也就是 Go 程序是不會等待其它 Go 協(xié)程的,
而此時由于 for 循環(huán)啟動的 Go 協(xié)程完全有可能還有運(yùn)行,從而導(dǎo)致任何沒有輸出任何內(nèi)容。
- 小概率有可能是 10 個 10
原因是: 假如 for 循壞啟動的 10 個 協(xié)程在 main 協(xié)程執(zhí)行完畢之前已運(yùn)行,由于協(xié)程的調(diào)度需要一定的時間,而通常這個時間是大于
for 循壞的時間的,所以等 10 個協(xié)程啟動的時候,for 循環(huán)已經(jīng)執(zhí)行到最后的變量 i=10 了,所以就會打印 10 個 10。
- 小概率有可能是亂序的 1 到 9 等
原因: 如果 Go 協(xié)程啟動的時間較快,在 for 循環(huán)每執(zhí)行到一個變量時該協(xié)程就會立即啟動,那么就會打印 1 到 9 不等,最終原因
還是與 Go 協(xié)程的調(diào)度機(jī)制有關(guān)。
那么問題來了,如果想要讓子協(xié)程執(zhí)行完畢后退出,有什么辦法呢?
我們可以使用 sync.WaitGroup 來實(shí)現(xiàn),請看下面代碼
func main() {var wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1) // 每啟動一個協(xié)程就加 1go func() {defer wg.Done() // 協(xié)程退出時自動減 1fmt.Println(i)}()}wg.Wait() // 等待所有協(xié)程執(zhí)行完畢
}
輸出結(jié)果為:
10
10
10
10
10
10
10
10
10
10
如果想要讓其打印出 0,1,2,3,4 … 等,需要怎樣修改代碼呢?
只需要在調(diào)用協(xié)程函數(shù)的時候傳入對應(yīng)的變量就行,如下代碼:
func main() {var wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1)go func(n int) {defer wg.Done()fmt.Println(n)}(i) // 傳入外面循環(huán)變量的值}wg.Wait()
}
參考:
https://mp.weixin.qq.com/s/gqqAazWUCp1ZtK7PebJe3g
總結(jié)
以上是生活随笔為你收集整理的Go 知识点(01)— 主协程与子协程执行顺序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028年中国玫瑰花行业市场研
- 下一篇: 2022-2028年中国激光脱毛仪行业市