1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| func main() { // runtime.GOMAXPROCS(1) // 1 因素1 cpu ch := make(chan int) go func() { for{ a := <- ch // for j:=0; j<1024*1024; j+=1{} // 2 因素2 // time.Sleep(time.Second) // 3 因素3 fmt.Println("goroutine 1 : ", a) } }() go func() { for{ a := <- ch // for j:=0; j<1024*1024; j+=1{} // 2 因素2 // time.Sleep(time.Second) // 3 因素3 fmt.Println("goroutine 2 : ", a) } }() for i := 0; i < 20; i++ { ch <- i } }
|
上面被注释的三行代码表示三个因素
- GOMAXPROCS 设置goroutine们由几个cpu分担执行 sets the maximum number of CPUs that can be executing
- 使得协程变成cpu运算密集型
- 使协程可以被挂起,出让cpu
注释掉 123 三行语句 得到结果1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| goroutine 2 : 0 goroutine 2 : 2 goroutine 2 : 3 goroutine 2 : 4 goroutine 2 : 5 goroutine 1 : 1 goroutine 2 : 6 goroutine 2 : 8 goroutine 1 : 7 goroutine 2 : 9 goroutine 2 : 11 goroutine 2 : 12 goroutine 2 : 13 goroutine 1 : 10 goroutine 2 : 14 goroutine 1 : 16 goroutine 2 : 15 goroutine 1 : 17 goroutine 1 : 19
|
通过结果可以看到,由哪个协程执行不确定
当把因素1取消注释,一个cpu执行,得到结果2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| goroutine 2 : 0 goroutine 2 : 1 goroutine 2 : 2 goroutine 2 : 3 goroutine 2 : 4 goroutine 2 : 5 goroutine 2 : 6 goroutine 2 : 7 goroutine 2 : 8 goroutine 2 : 9 goroutine 2 : 10 goroutine 2 : 11 goroutine 2 : 12 goroutine 2 : 13 goroutine 2 : 14 goroutine 2 : 15 goroutine 2 : 16 goroutine 2 : 17 goroutine 2 : 18
|
通过结果可以看到只有一个协程消费了整个channel
设置runtime.GOMAXPROCS(n) // n>=2 时,结果就如结果1
然后我们先注释掉因素1, 取消对因素2的注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| goroutine 2 : 0 goroutine 1 : 1 goroutine 2 : 2 goroutine 1 : 3 goroutine 2 : 4 goroutine 1 : 5 goroutine 2 : 6 goroutine 1 : 7 goroutine 2 : 8 goroutine 1 : 9 goroutine 2 : 10 goroutine 1 : 11 goroutine 2 : 12 goroutine 1 : 13 goroutine 2 : 14 goroutine 1 : 15 goroutine 2 : 16 goroutine 1 : 17 goroutine 2 : 18
|
可以看到让每个协程计算密集后,协程开始交替执行
注释掉因素1和, 取消注释因素3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| goroutine 1 : 0 goroutine 2 : 1 goroutine 1 : 2 goroutine 2 : 3 goroutine 1 : 4 goroutine 2 : 5 goroutine 1 : 6 goroutine 2 : 7 goroutine 1 : 8 goroutine 2 : 9 goroutine 1 : 10 goroutine 2 : 11 goroutine 1 : 12 goroutine 2 : 13 goroutine 1 : 14 goroutine 2 : 15 goroutine 1 : 16 goroutine 2 : 17 goroutine 1 : 18
|
同样协程交替执行
在取消注释因素1和2,注释因素3情况下,得到结果是不确定的,通常是一个协程(不确定哪一个)消费了整个或大部分channel
试着增加协程cpu运算密集度,当计算增加到一定时候,协程又开始交替执行
最后取消注释因素1和3,注释2,得到结果同样是协程交替执行
总结:go在处理大的计算或者io的时候会均匀的分配cpu给goroutine,gorautine计算密度很小或没有发生IO等需要挂起和谦让执行机会的时候,goroutine不会出让cpu。。