将进程固定到任何遵循亲和力的CPU

时间:2018-09-22 22:16:22

标签: linux scheduler affinity

假设我想以编程方式将当前进程固定到单个CPU,但是我不在乎哪个CPU。

使用sched_setaffinity和固定CPU号(可能是0)的一种简单方法,因为应该始终有一个“ CPU 0” 1

但是,如果已将进程的亲和力设置为现有CPU的子集,而不包括您选择的CPU,例如通过使用taskset启动,则此方法将失败。

所以我想选择“任何CPU”固定,但只能从当前亲和力掩码允许的CPU中选择。这是一种方法:

cpu_set_t cpu_set;
if (sched_getaffinity(0, sizeof(cpu_set), &cpu_set)) {
    err("failed while getting existing cpu affinity");
}
for (int cpu = 0; cpu < CPU_SETSIZE; cpu++) {
    if (CPU_ISSET(cpu, &cpu_set)) {
        CPU_ZERO(cpu_set);
        CPU_SET(cpu, &cpu_set);
    }
}
int result = sched_setaffinity(0, sizeof(cpu_set), &cpu_set);

基本上,我们获得了当前的亲和力掩码,然后遍历每个可能的CPU寻找允许的第一个掩码,然后传递一个仅将此CPU设置为sched_setaffinity的掩码。

但是,如果当前亲和力掩码在getset调用之间已更改,则set调用将失败。可以解决这种比赛情况吗?


1 尽管CPU零并不总是在线

2 个答案:

答案 0 :(得分:2)

您可以使用getcpu()来发现您的进程正在其中运行的CPU,并使用结果来设置与该CPU的关联性:

unsigned mycpu=0;
if( -1 == getcpu(&mycpu,NULL,NULL) ) {
   // handle error
}

调度程序可能会遵守所有已建立的CPU关联性规则,因此getcpu()调用将返回允许该进程在其上运行的CPU。

相似性集仍然有可能发生变化,但这似乎是极不可能的情况,并且所允许的CPU可能会在将来某个时候受到影响,而不受相关进程的控制。

我想您可以在sched_setaffinity()调用中检测到错误,然后重试该过程,直到setaffinity调用起作用为止。

答案 1 :(得分:0)

考虑到进程的亲和力掩码可以随时更改,您可以迭代地尝试将进程固定到当前CPU并在成功后停止。

cpu_set_t cpu_set;

int cpu = 0;
int result = -1;

while (result<0){

    cpu = sched_getcpu();
    if (cpu>0){
        CPU_ZERO(&cpu_set);
        CPU_SET(cpu, &cpu_set);
        result = sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
    }
}