关于sched.h中cpu_set_t结构定义及位域解释的疑问
关于cpu_set_t结构体的理解
你对定义的理解没有偏差,cpu_set_t确实是一个内嵌了__bits数组的结构体,数组的元素类型是unsigned long int,长度为CPU_SETSIZE / __CPU_BITS。
作为位掩码的实现逻辑
它本质是用数组拼接出了一个总长度等于CPU_SETSIZE的连续位空间,每一位对应一个CPU核心:
__CPU_BITS的值等于unsigned long int的位宽,32位系统下为32,64位系统下为64CPU_SETSIZE是操作系统预设的最大支持CPU核心数,主流发行版默认值为1024
所以__bits数组的总位数刚好是(CPU_SETSIZE / __CPU_BITS) * __CPU_BITS = CPU_SETSIZE,刚好能覆盖所有支持的CPU核心编号。
位操作的封装
用户不需要直接操作__bits数组的元素,操作系统提供了标准宏来完成所有掩码操作,底层会自动计算对应的数组下标和位偏移:
CPU_ZERO(&cpu_set):初始化掩码,将所有位清零CPU_SET(cpu_id, &cpu_set):将编号为cpu_id的CPU对应的位设为1,表示允许进程/线程运行在该核心上CPU_CLR(cpu_id, &cpu_set):将编号为cpu_id的CPU对应的位清零CPU_ISSET(cpu_id, &cpu_set):检查编号为cpu_id的CPU对应的位是否为1
举个实际计算例子:64位系统下__CPU_BITS为64,要操作编号为70的CPU:
- 数组下标:
70 / 64 = 1,对应__bits[1]元素 - 位偏移:
70 % 64 = 6,对应__bits[1]的第6位
底层宏会自动对该位做与/或/异或操作,用户感知不到数组的存在,看起来就像直接操作一个连续的位域一样。
封装为结构体的原因
主要是为了类型安全,避免普通数组被误传到CPU亲和性相关的API中,同时也方便后续扩展实现,上层调用代码不需要跟随底层逻辑修改。
内容的提问来源于stack exchange,提问作者Pranav Krishnan
相关产品推荐
相关产品推荐

