下面的函数用于配置go运行使用的最大处理器:
runtime.GOMAXPROCS(num)
目的
测试runtime.GOMAXPROCS(num)
函数的作用, 以及go语言在不同数量的协程下, 创建的线程数量与对CPU的利用率, 测试器并发特性;
配置
测试方法
测试方法, 在程序中写多个协程, 每个协程都有一个大循环,如下代码:
go func() {
x := 0
fmt.Println(`******`)
for {
x += 2
if x%20000000000 == 0 {
fmt.Println(`GO1`, x)
}
}
}()
默认情况
默认情况下(即不配置最大处理器个数), go启动后会根据计算机的CPU数来创建线程. 如我的机子有2个CPU, go程序有6个协程, 运行后创建了4个线程, 但只有2个线程为工作线程(即与CPU数一样).
runtime.GOMAXPROCS(1)
+ 2协程
最大CPU数 | 程序协程数 | 运行后总线程数 | 协程占用线程数 | 协程计算用到的CPU数 |
---|
2 | 2 | 4 | 1 | 1 |
runtime.GOMAXPROCS(2)
+ 2协程
最大CPU数 | 程序协程数 | 运行后总线程数 | 协程占用线程数 | 协程计算用到的CPU数 |
---|
2 | 4 | 4 | 2 | 2 |

runtime.GOMAXPROCS(4)
+ 4协程
最大CPU数 | 程序协程数 | 运行后总线程数 | 协程占用线程数 | 协程计算用到的CPU数 |
---|
2 | 6 | 4 | 4 | 2 |
runtime.GOMAXPROCS(6)
+ 2协程
最大CPU数 | 程序协程数 | 运行后总线程数 | 协程占用线程数 | 协程计算用到的CPU数 |
---|
2 | 4 | 4 | 2 | 2 |
runtime.GOMAXPROCS(6)
+ 6协程
最大CPU数 | 程序协程数 | 运行后总线程数 | 协程占用线程数 | 协程计算用到的CPU数 |
---|
2 | 6 | 7 | 6 | 2 |

总结
- go 运行后默认会开启4个线程;
- 如果配置了最大CPU使用数N, 则无论创建多少协程, 最多使用的线程数量不会超过N;
- go创建的线程数量与
runtime.GOMAXPROCS(6)
有关, 且会岁协程数量增加动态增加线程(上限为配置的数量); - 为了go的最有性能, 最大处理器使用数量应该为CPU的数量, 即
runtime.GOMAXPROCS(runtime.NumCPU())
, 超过这个值, 则随着协程的增加, 线程的数量也会大于CPU的数量, 这样反而在协程切换时会需要CPU进行线程的切换, 影响性能; - 默认情况下, go会启动与CPU数相等的计算线程为协程工作(可能还有额外的线程);