假设我想以编程方式将当前进程固定到单个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
的掩码。
但是,如果当前亲和力掩码在get
和set
调用之间已更改,则set
调用将失败。可以解决这种比赛情况吗?
1 尽管CPU零并不总是在线 。
答案 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);
}
}