利用时间片分割进程,致使宏观上A,B,C同时执行(并发)
CPU利用率包含了执行和切换,进程/线程的数量越多,切换成本也会增大
最大并行数:GOMAXPROCS
work stealing: 偷其他队列的G
hand off: 当前G1阻塞,创建/唤醒一个thread,移动当前本地队列至其上
func newTask() {i := 0for {i++fmt.Printf("new Goroutine: i = %d\n", i)time.Sleep(1 * time.Second)}
}func main() {/*go newTask()i := 0for {i++fmt.Printf("main Goroutine: i = %d\n", i)time.Sleep(1 * time.Second)}*/go func() {defer fmt.Println("A.defer")func() {defer fmt.Println("B.defer")runtime.Goexit() // 退出Goroutinefmt.Println("B")}()fmt.Println("A")}()for {time.Sleep(1 * time.Second)}
}
// channel
func main() {// 无缓存c := make(chan int)go func() {defer fmt.Println("goroutine end")fmt.Println("goroutine running")c <- 114514 // 114514 发送到 c}()num := <-c // c 中接收数据并赋值给numfmt.Printf("num = %d\n", num)fmt.Println("main goroutine end")
}
func main() {// 有缓存c := make(chan int, 3)fmt.Println("len(c) = ", len(c), ", cap(c) = ", cap(c))go func() {defer fmt.Println("子go结束")for i := 0; i < 3; i++ {c <- ifmt.Println("子go正在运行:len(c) = ", len(c), "cap(c) = ", cap(c))fmt.Println("发送元素 = ", i)}}()time.Sleep(2 * time.Second)for i := 0; i < 3; i++ {num := <-cfmt.Println("num = ", num)}fmt.Println("main 结束")}
func main() {// channel 需要初始化c := make(chan int)go func() {for i := 0; i < 5; i++ {c <- i}// 关闭 channel 的发送端close(c)}()// 写法一// 接收 channel 数据之前先判断 channel 状态for {data, ok := <-cif ok {println("data: ", data)} else {break}}// 写法二// 无数据自动阻塞for data := range c {fmt.Println("data:", data)}fmt.Println("Main Finished")
}
// select 语句 控制多个 channel
func fib(c, quit chan int) {x, y := 1, 1for {select {case c <- x:x, y = y, x+ycase <-quit:fmt.Println("quit")return}}
}func main() {c := make(chan int)quit := make(chan int)go func() {for i := 0; i < 6; i++ {fmt.Println(<-c)}quit <- 0}()fib(c, quit)
}
reference
B站刘丹冰Aceld