golang的GOMAXPROCS
-
介绍
GOMAXPROCS是golang运行时环境的一个参数,控制着同时执行golang代码的操作系统线程的最大数量(M),即影响调度器分配Goroutine到多少个操作系统线程。这些线程由操作系统分配到机器的逻辑核心(P)上执行。
当GOMAXPROCS=1时,所有Goroutine在单线程上并发运行(通过时间片切换,非真正并行)。
当GOMAXPROCS>1时,Goroutine可以被分配到多个线程,这些线程又可以被分配到不同的逻辑核心上,从而并行执行在多核cpu上。
-
Go 1.4 及之前版本,默认 GOMAXPROCS=1。 Go 1.5 及之后版本,GOMAXPROCS = 当前机器的逻辑 CPU 核心数(通过 runtime.NumCPU() 获取)。
-
设置GOMAXPROCS
// 环境变量方式
在go程序运行前,添加/修改 GOMAXPROCS 环境变量
export GOMAXPROCS=4 # Linux/Mac
set GOMAXPROCS=4 # Windows
// 代码方式
在程序开头,使用runtime包的GOMAXPROCS方法设置
runtime.GOMAXPROCS(4)
// 其中,runtime.GOMAXPROCS接收的值如果小于等于0,会返回当前的GOMAXPROCS值,而不修改。
// 两种方式同时设置的情况下,环境变量方式优先级会更高 -
小坑:docker内运行golang程序
// 在docker内,golang程序感知cpu核心数的功能可能不准确。比如本人遇到的情况,容器cpu设置250m(即0.25核)的情况下,golang程序却感知到了4个核心,而机器实际是8个核心。
// 这种情况下,golang默认情况下会设置GOMAXPROCS=4,会将协程分配给4个操作线程,而实际能用上的逻辑核心是1,这就导致4个线程争抢一个逻辑核心的资源,那么就会带来不必要的线程上下文切换消耗。
// 如果面对cpu核心更多的机器,比如32核心,那么这个问题就会更加严重。
// 所以在docker中运行golang程序,最好自己设置一下GOMAXPROCS。golang官方已经出了相关的提案,希望golang能正确感知容器可利用的核心数,也许未来的版本中,就不需要自己设置了。
浙公网安备 33010602011771号