如何限制go程序能使用的CPU核数?

一、在编译阶段(go build)做不到限制go程序能使用的CPU核数

因为在编译阶段(go build):

  • 不知道程序将运行在哪台机器
  • 不知道有多少 CPU、是否在容器中
  • Go 编译产物是 通用二进制,不绑定运行环境

所以 不存在编译期的 CPU 限制选项。

编译参数:

  • -gcflags
  • -ldflags
  • GOARCH / GOOS

都不能限制 CPU 核数。

二、官方 & 推荐的运行时方式(进程内)

1 环境变量(最常用)

GOMAXPROCS=4 ./app

限制4个CPU核数,等价于代码:runtime.GOMAXPROCS(4)

无需改代码

进程启动时生效

Go 1.5+ 支持

Go 1.21+ 默认会自动感知容器 CPU 限额

2 代码里设置

runtime.GOMAXPROCS(4)

只能影响 Go 调度器

不限制 OS 线程的创建(那是另一回事)。

三、操作系统 / 容器层(更“硬”的限制)

1 Docker / Kubernetes(强烈推荐)

Docker:

docker run --cpus=2 my-go-app

Kubernetes:

resources:
  limits:
    cpu: "2"

Go runtime 会:

  • 看到 cgroup 限制
  • 自动设置 GOMAXPROCS = 2(Go 1.21+)

2 Linux taskset(CPU 亲和性)

taskset -c 0,1 ./app

限制进程只能跑在 CPU 0、1

对所有语言生效

Go runtime 会“被动服从”

3 cgroups(底层方式)

echo 200000 > cpu.cfs_quota_us
echo 100000 > cpu.cfs_period_us

容器本质用的就是这种方式

最底层、最硬核