BUGS

在具有glibc 2.8和更早版本的32位平台上,CPU_ALLOC()分配所需空间的两倍,CPU_ALLOC_SIZE()返回的值应为两倍。此错误不应影响程序的语义,但会导致内存浪费和在动态分配的CPU集合上运行的宏的较低效率的操作。这些错误已在glibc 2.9中修复。

遵循规范

这些接口是特定于Linux的。

CPU_SET - Linux手册页

Linux程序员手册 第3部分
更新日期: 2020-04-11

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

说明

cpu_set_t数据结构表示一组CPU。 sched_setaffinity(2)和类似接口使用CPU集。

数据类型cpu_set_t被实现为位掩码。但是,数据结构应视为不透明的:CPU集的所有操作都应通过此页中描述的宏来完成。

提供以下宏以在CPU集集上运行:

CPU_ZERO()
清除集,使其不包含任何CPU。
CPU_SET()
添加CPU cpu进行设置。
CPU_CLR()
从集中删除CPU cpu。
CPU_ISSET()
测试以查看CPU cpu是否为set的成员。
CPU_COUNT()
返回设置的CPU数。

在指定了cpu参数的情况下,它不应产生副作用,因为上述宏可能会多次评估该参数。

系统上的第一个CPU对应于cpu值0,下一个CPU对应于cpu值1,依此类推。由于CPU可以动态脱机或以其他方式不存在,因此不应对特定CPU可用或一组CPU连续进行任何假设。常量CPU_SETSIZE(当前为1024)指定的值比可以存储在cpu_set_t中的最大CPU数大一。

以下宏在CPU集上执行逻辑操作:

CPU_AND()
将集srcset1和srcset2的交集存储在destset中(它可能是源集之一)。
CPU_OR()
将集合srcset1和srcset2的并集存储在destset中(这可能是源集之一)。
CPU_XOR()
将集srcset1和srcset2的XOR存储在destset中(这可能是源集之一)。 XOR表示srcset1或srcset2中的一组CPU,但不能同时位于这两者中。
CPU_EQUAL()
测试两个CPU集是否包含完全相同的CPU。

Dynamically sized CPU sets

由于某些应用程序可能需要动态调整CPU集大小的能力(例如,分配比标准cpu_set_t数据类型定义的集大的集),因此glibc现在提供了一组宏来支持此设置。

以下宏用于分配和取消分配CPU集:

CPU_ALLOC()
分配足够大的CPU集以容纳介于0到num_cpus-1之间的CPU。
CPU_ALLOC_SIZE()
返回将CPU保持在0到num_cpus-1范围内所需的CPU集的大小(以字节为单位)。该宏提供了可用于下面描述的CPU _ * _ S()宏中的setsize参数的值。
CPU_FREE()
释放先前由CPU_ALLOC()分配的CPU集。

名称以" _S"结尾的宏是不带后缀的类似名称的宏的类似物。这些宏执行与模拟操作相同的任务,但对大小为setsize字节的动态分配的CPU集进行操作。

名称

CPU_SET,CPU_CLR,CPU_ISSET,CPU_ZERO,CPU_COUNT,CPU_AND,CPU_OR,CPU_XOR,CPU_EQUAL,CPU_ALLOC,CPU_ALLOC_SIZE,CPU_FREE,CPU_SET_S,CPU_CLR_S,CPU_ISSET_S,CPU_IP0_S,CPU_COUNT_S,CPU_AND_S,CPU_AND_S,CPU_AND_S,CPU_AND_S,CPU_OR_S, CPU_XOR_S, CPU_EQUAL_S - 用于操作CPU集的宏

版本

glibc 2.3.3中添加了CPU_ZERO(),CPU_SET(),CPU_CLR()和CPU_ISSET()宏。

CPU_COUNT()首先出现在glibc 2.6中。

CPU_AND(),CPU_OR(),CPU_XOR(),CPU_EQUAL(),CPU_ALLOC(),CPU_ALLOC_SIZE(),CPU_FREE(),CPU_ZERO_S(),CPU_SET_S(),CPU_CLR_S(),CPU_ISSET_S(),CPU_AND_S(),CPU_OR ),CPU_XOR_S()和CPU_EQUAL_S()首次出现在glibc 2.7中。

备注

要复制CPU集,请使用memcpy(3)。

由于CPU集是以长字为单位分配的位掩码,因此,动态分配的CPU集中的CPU实际数量将舍入为sizeof(unsigned long)的下一个倍数。应用程序应考虑这些额外位的内容未定义。

尽管名称相似,但请注意,常量CPU_SETSIZE表示cpu_set_t数据类型中的CPU数量(因此,它实际上是位掩码中的位数),而CPU _ * _ S()的setsize参数表示宏的大小以字节为单位。

概要中显示的参数和返回值的数据类型提示每种情况下的预期结果。但是,由于这些接口是作为宏实现的,因此如果违反建议,编译器不一定会捕获所有类型错误。

语法

#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <sched.h>

void CPU_ZERO(cpu_set_t *set);

void CPU_SET(int cpu, cpu_set_t *set);
void CPU_CLR(int cpu, cpu_set_t *set);
int  CPU_ISSET(int cpu, cpu_set_t *set);

int  CPU_COUNT(cpu_set_t *set);

void CPU_AND(cpu_set_t *destset,
             cpu_set_t *srcset1, cpu_set_t *srcset2);
void CPU_OR(cpu_set_t *destset,
             cpu_set_t *srcset1, cpu_set_t *srcset2);
void CPU_XOR(cpu_set_t *destset,
             cpu_set_t *srcset1, cpu_set_t *srcset2);

int  CPU_EQUAL(cpu_set_t *set1, cpu_set_t *set2);

cpu_set_t *CPU_ALLOC(int num_cpus);
void CPU_FREE(cpu_set_t *set);
size_t CPU_ALLOC_SIZE(int num_cpus);

void CPU_ZERO_S(size_t setsize, cpu_set_t *set);

void CPU_SET_S(int cpu, size_t setsize, cpu_set_t *set);
void CPU_CLR_S(int cpu, size_t setsize, cpu_set_t *set);
int  CPU_ISSET_S(int cpu, size_t setsize, cpu_set_t *set);

int  CPU_COUNT_S(size_t setsize, cpu_set_t *set);

void CPU_AND_S(size_t setsize, cpu_set_t *destset,
             cpu_set_t *srcset1, cpu_set_t *srcset2);
void CPU_OR_S(size_t setsize, cpu_set_t *destset,
             cpu_set_t *srcset1, cpu_set_t *srcset2);
void CPU_XOR_S(size_t setsize, cpu_set_t *destset,
             cpu_set_t *srcset1, cpu_set_t *srcset2);

int  CPU_EQUAL_S(size_t setsize, cpu_set_t *set1, cpu_set_t *set2);

返回值

如果设置了cpu,则CPU_ISSET()和CPU_ISSET_S()返回非零;否则,返回0。否则,返回0。

CPU_COUNT()和CPU_COUNT_S()返回设置的CPU数。

如果两个CPU集相等,则CPU_EQUAL()和CPU_EQUAL_S()返回非零;否则,返回0。否则返回0。

CPU_ALLOC()成功返回一个指针,失败则返回NULL。 (错误与malloc(3)相同。)

CPU_ALLOC_SIZE()返回存储指定基数的CPU集所需的字节数。

其他函数不返回值。

示例

以下程序演示了用于动态分配的CPU集的一些宏的用法。

#define _GNU_SOURCE
#include <sched.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>

int
main(int argc, char *argv[])
{
    cpu_set_t *cpusetp;
    size_t size;
    int num_cpus, cpu;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s <num-cpus>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    num_cpus = atoi(argv[1]);

    cpusetp = CPU_ALLOC(num_cpus);
    if (cpusetp == NULL) {
        perror("CPU_ALLOC");
        exit(EXIT_FAILURE);
    }

    size = CPU_ALLOC_SIZE(num_cpus);

    CPU_ZERO_S(size, cpusetp);
    for (cpu = 0; cpu < num_cpus; cpu += 2)
        CPU_SET_S(cpu, size, cpusetp);

    printf("CPU_COUNT() of set:    %d\n", CPU_COUNT_S(size, cpusetp));

    CPU_FREE(cpusetp);
    exit(EXIT_SUCCESS);
}
日期:2019-08-20 17:59:38 来源:oir作者:oir