// 主線程結束後 全部協程都會一塊兒結束 // 在4個go程中結束時向chan c寫入true // 開啓go程後 在主線程中循環對管道c取值,取出4個true 說明go程執行完畢 再執行主線程並退出 func main() { c := make(chan bool, 5) fmt.Printf("type %T len %d cap %d\n", c, len(c), cap(c)) go test("go程1-", c) go test("go程2-", c) go test("go程3-", c) go test("go程4-", c) for i := 0; i < 4; i++ { v := <-c log.Println(v) } fmt.Println("goroutine over") } func test(name string, c chan bool) { for i := 0; i < 10; i++ { fmt.Println(name, i) } c <- true }
MPGgolang
一個GO程序執行時可能有多個M(主線程)在運行數據庫
每一個M中都有一個P(協程上下文)多線程
每一個P都掛着一個G(協程)隊列併發
P爲G的執行提供上下文環境操作系統
同一時刻,一個P下只有一個G在執行,可是G隊列中的G能夠快速切換執行線程
一個Go程序有多個M,這些M有些在同一個CPU,有些在不一樣的CPU上運行,至關於多進程並行執行code
在同一個CPU上的M至關於多個線程併發執行協程
同一個M中的多個G 是多協程 併發執行隊列
在同一個CPU上,當一個M0執行的G0執行耗時的操做如查詢數據庫,M0主線程被阻塞,對應的P下的G隊列中其餘協程就沒法執行,這時會建立新的M1主線程(或者從線程池取),將M0下的G隊列交給M1執行進程
協程遇到阻塞,使用多線程讓其餘協程繼續併發執行
go1.8以後默認使用所有CPU
runtime.NumCPU() // get當前機器的CPU數量 runtime.GOMAXPROCS(number) // 設置golang程序執行時使用的CPU數