affinity.get_process_affinity_mask(pid)返回ValueError 22

时间:2014-07-01 10:50:14

标签: python multithreading cpu affinity

我想将我的线程工作者放在某个CPU上(我想测试GIL如何影响我的程序......),我找到了一个名为affinity的第三方库。 我使用了pip install affinity来使它在我的VM(Linux)中可用,不幸的是,我收到了以下错误:

>>>pid = os.getpid()
>>>affinity.get_process_affinity_mask(pid)
Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: (22, 'Invalid argument')

来自代码洞察,它应该适用于Linux平台:

...
elif sys.platform in ('linux2'):
from _affinity import set_process_affinity_mask, get_process_affinity_mask
...

有人能给我一些关于这个错误的线索吗?或者我可以使用其他方式吗?

1 个答案:

答案 0 :(得分:0)

查看C代码和sched_getaffinity的手册页,我不会感到惊讶它可能会因为无效的参数而失败&#39;。 C代码传入一个unsigned long,函数需要一个cpu_set_t,最多可以有128个无符号长整数。

我对cpu_set_t结构了解不多,但从表面上看,每个物理CPU可能只有一个值,其中单个核心表示为其中一个值中的位。在这种情况下,我希望这个模块在任何具有多个CPU的计算机上都会失败。

我的系统是单CPU双核,因此该模块适合我。您的VM是否配置了多个物理CPU?作为测试,尝试将其重新配置为只有一个具有多个内核,并查看您是否更成功。

如果我是对的,唯一的办法是修改C模块以正确处理cpu_set_t结果,可能使用CPU_SET(3)中描述的宏。

您的VM环境是什么? VM软件,CPU /核心数,Linux版本? 试试这个测试程序,看看你的输出是否有任何不同:

$ cat test.c 
#include <stdio.h>
// The CPU_SET man page says to use the second definition, but my system
// wouldn't compile this code without the first one.
#define __USE_GNU
#define _GNU_SOURCE
#include <sched.h>
#include <errno.h>

int main(void) {
    cpu_set_t cur_mask;
    unsigned int len = sizeof(cpu_set_t);

    if (sched_getaffinity(0, len, &cur_mask) < 0) {
        printf("Error: %d\n", errno);
        return errno;
    }

    int cpu_count = CPU_COUNT(&cur_mask);
    printf("Cpu count: %d and size needed: %d\n", cpu_count, CPU_ALLOC_SIZE(cpu_count));
    return 0;
}
$ gcc -std=c99 test.c 
$ ./a.out 
Cpu count: 2 and size needed: 8

在我的系统上,似乎一个无符号长度足以容纳多达64个CPU,因此它看起来比我想象的要简单得多。不同的硬件/架构/内核版本可能总是不同。