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

一种使用带有固定CPU编号的sched_setaffinity的简单方法,可能是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零并不总是在线。

最佳答案

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

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

大概所有已存在的CPU关联性规则都将被调度程序接受,因此getcpu()调用将返回允许该进程运行的CPU。

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

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

关于linux - 将进程固定到任何尊重亲缘关系的CPU,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52461322/

10-16 20:46