进程的 CPU 亲和性掩码决定了它可以运行的 CPU 集。在多处理器系统上,设置 CPU 亲和性掩码可以用来获得性能优势。例如,通过将一个 CPU 专用于特定进程(即,将该进程的亲和性掩码设置为指定单个 CPU,并将所有其他进程的亲和性掩码设置为排除该 CPU),可以确保该进程的最大执行速度。将进程限制在单个 CPU 上运行还可以避免由于进程停止在一个 CPU 上执行然后在另一个 CPU 上重新执行而导致的缓存失效造成的性能损失。
CPU 亲和性掩码由cpu_set_t结构(一个“CPU 集”)表示,该结构由mask指向。提供四个宏来操作 CPU 集。CPU_ZERO() 清除一个集合。CPU_SET() 和CPU_CLR() 分别向集合中添加和删除给定的 CPU。CPU_ISSET() 测试一个 CPU 是否是集合的一部分;这在sched_getaffinity() 返回后很有用。系统上第一个可用的 CPU 对应于cpu值为 0,下一个 CPU 对应于cpu值为 1,以此类推。常量CPU_SETSIZE (1024) 指定一个值,该值比可以存储在 CPU 集中的最大 CPU 编号大 1。
sched_setaffinity() 将 ID 为pid的进程的 CPU 亲和性掩码设置为mask指定的值。如果pid为零,则使用调用进程。参数cpusetsize是指向mask的数据的长度(以字节为单位)。通常,此参数将指定为sizeof(cpu_set_t)。
如果pid指定的进程当前未在mask中指定的 CPU 之一上运行,则该进程将迁移到mask中指定的 CPU 之一。
sched_getaffinity() 将 ID 为pid的进程的亲和性掩码写入mask指向的cpu_set_t结构中。cpusetsize参数指定mask的大小(以字节为单位)。如果pid为零,则返回调用进程的掩码。
通过fork(2) 创建的子进程继承其父进程的 CPU 亲和性掩码。亲和性掩码在execve(2) 中被保留。
本手册页描述了 CPU 亲和性调用的 glibc 接口。实际的系统调用接口略有不同,其中mask的类型为unsigned long *,这反映了 CPU 集的底层实现是一个简单的位掩码。成功时,原始sched_getaffinity() 系统调用返回内核内部用来表示 CPU 集位掩码的cpumask_t数据类型的 size(以字节为单位)。
历史
CPU 亲和性系统调用是在 Linux 内核 2.5.8 中引入的。库接口是在 glibc 2.3 中引入的。最初,glibc 接口包含一个cpusetsize参数。在 glibc 2.3.2 中,cpusetsize参数被删除,但在 glibc 2.3.4 中又恢复了这个参数。