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 中,協程就是乙個包含程式執行時的資訊的結構體,如棧,程式計數器,...