// 主线程结束后 全部协程都会一块儿结束 // 在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数