golang中如何将一个进程绑定到一组cpu上?
Posted
技术标签:
【中文标题】golang中如何将一个进程绑定到一组cpu上?【英文标题】:How to bind a process to a set of cpu in golang? 【发布时间】:2021-09-29 18:34:59 【问题描述】:我使用 os/exec pkg 来运行一个进程。我想检查它的 cpu 亲和力并修改它以将进程绑定到特定的 cpu 集。我发现
func SchedSetaffinity(pid int, set *CPUSet) error
这个函数在golang.org/x/sys/unix package。但是,它说它只是将线程绑定到特定的 cpu。我不知道它是否适用于流程。我想知道如何获得 CPUSet。这是我需要定义的值吗?
【问题讨论】:
根据我对这个主题的了解,进程不在 CPU 上运行;来自进程的线程是。您可能希望找到与进程关联的线程并设置它们的亲和性。 @Carcigenicate 来自 windows 用户,线程关联掩码必须是进程关联掩码的子集,它在进程可能运行的处理器组上运行。 idk 如果一个进程可以跨越多个处理器组...docs.microsoft.com/en-us/windows/win32/procthread/…我只能假设 linux 也支持类似的机制来支持许多核心系统上的更高级别的调度 @Aaron 我承认,我已经研究了大约一年了,所以我的评论可能会被取消。 kernel.org/doc/html/latest/admin-guide/cgroup-v2.html#cpuset 了解 cgroups v2 中 cpuset 的详细信息,然后可以使用 github.com/containerd/cgroups 在 Golang 中进行设置 【参考方案1】:任务集:要使进程在特定 CPU 上运行,您可以在 linux 中使用命令“任务集”。因此,您可以得出一个基于“taskset -p [mask] [pid]”的逻辑,其中掩码表示特定进程应在其中运行的核心,前提是整个程序以 GOMAXPROCS=1 运行。
pthread_setaffinity_np :您可以使用 cgo 并到达调用 pthread_setaffinity_np 的逻辑,因为 Go 在 cgo 模式下使用 pthreads。 (pthread_attr_setaffinity_np()函数将attr引用的线程属性对象的CPU亲和掩码属性设置为cpuset中指定的值。)
Go helps in incorporation of affinity control 通过“SchedSetaffinity”可以检查是否将线程限制到特定内核。因此,您可以得出使用“SchedSetaffinity(pid int, set *CPUSet)”的逻辑,该逻辑设置由 pid 指定的线程的 CPU 关联掩码。如果 pid 为 0,则使用调用线程。
需要注意的是,GOMAXPROCS 变量限制了可以同时执行用户级 Go 代码的操作系统线程数。如果它 > 1,那么您可以使用 Go 的 runtime.LockOSThread 将当前 goroutine 固定到正在运行的当前线程。调用的 goroutine 将始终在该线程中执行,并且没有其他 goroutine 将在其中执行,直到调用的 goroutine 对 UnlockOSThread 的调用次数与对 LockOSThread 的调用次数一样多。
cgroups : 还可以选择使用cgroups,它有助于以受控和可配置的方式分层组织进程并沿层次结构分配系统资源。在这里,有一个称为 cpuset 的子系统,它可以分配单个 CPU(在多核系统上)和内存节点以在 cgroup 中进行处理。 cpuset 列出了此 cgroup 中的任务要使用的 CPU。 CPU 编号是逗号分隔的数字或范围。例如:
#cat cpuset.cpus
0-4,6,8-10
一个进程只能在它所属的 cpuset 中的 CPU 上运行,并且只能在该 cpuset 中的内存节点上分配内存。需要注意的是,所有进程在创建时都放在父进程所属的cgroup中,一个进程可以迁移到另一个cgroup。进程的迁移不会影响已经存在的后代进程。
【讨论】:
以上是关于golang中如何将一个进程绑定到一组cpu上?的主要内容,如果未能解决你的问题,请参考以下文章