go協程之間的執行順序以及和主協程的執行順序

2021-10-22 19:28:40 字數 1899 閱讀 2420

package main

var a string

func f()

func hello()

func main()

輸出:

不確定

可能呼叫hello函式的某一時刻列印;可能hello函式執行完成後列印;可能不列印"hello world"

原因:

執行go f()語句建立goroutine和hello函式是在同乙個goroutine中執行, 根據語句的書寫順序可以確定goroutine的建立發生在hello函式返回之前, 但是新建立goroutine對應的f()的執行事件和hello函式返回的事件則是不可排序的,也就是併發的。

故不確定f()執行列印語句和hello函式返回誰先誰後,所以可能在hello函式返回之前或返回之後列印;如果hello函式返回了且main函式也退出了,那麼程式就退出了,列印語句不會再執行。

package main

import (

"fmt"

)func main() ()

}

輸出:

原因:

main函式執行到第9行時,要從通道ch取值,此時main協程會被阻塞,等待向通道存值的操作;而在main協程中程式是順序執行的,如果第9行一直阻塞著,下面的go協程也不可能執行,main協程也永遠等不來向通道存值的操作;執行時會檢查主協程是否在等待,如果是則判定為死鎖。

package main

import (

"time"

)func main() ()

go func() ()

time.sleep(time.second * 2)

print("main done")

}

輸出:

main done

原因:

main函式順序執行到第8行時,此時擺在面前的有3個協程:2個go協程和main協程,它們的執行是併發的,誰都有可能先發生。main協程第19行休眠2s,保證main協程不會太快執行完,因為如果main函式執行結束,程式會退出,不會等待其他非main協程結束;不管這2個go協程哪個先執行,都會導致2個go協程都被阻塞等待;此時main協程休眠完,執行完第20行,程式退出。儘管2個go協程互相阻塞,但和main協程無關,故不會報死鎖錯誤。

package main

var done = make(chan bool, 1)

var msg string

func agoroutine()

func main()

輸出:

2種可能:

列印為空或列印"hello world"

原因:

通道done是帶緩衝的,main協程done 接收操作將不會被後台協程的接收操作阻塞,若第14行列印語句早於agoroutine協程對msg賦值執行,則列印為空;若msg賦值早於列印語句執行,則列印"hello world"。

參考:

python協程執行阻塞機制的坑

廢話不多說,直接看兩段 阻塞 import random import gevent import time import gevent.monkey gevent.monkey.patch all 自動切換 若沒有這行 若sleep則會順序執行 小明1 3,小紅1 3,小剛1 3實現協程 需要等待...

Go語言的協程,系統執行緒以及CPU管理

建立系統執行緒以及在系統執行緒間切換,會對程式的記憶體和效能造成較大的開銷。go 的目標是盡量利用 cpu 多核資源。設計之初就考慮了高併發性。為了達到這個目標,go擁有乙個將協程排程到系統執行緒執行的排程器。這個排程器定義了三個核心概念,在go原始碼中是這樣解釋的 m必須有乙個相關聯的p才能執行g...

go開攜程訪問mysql Go 協程的開啟和退出

illustration created for a journey with go made from the original go gopher,created by renee french.本文基於 go 1.14。在 go 中,協程就是乙個包含程式執行時的資訊的結構體,如棧,程式計數器,...