从多个线程调用NumPy的C API函数有什么含义?

ide*_*ide 7 python numpy python-c-api gil

这是一项有风险的业务,我理解Global Interpreter Lock是一个强大的并行性敌人.但是,如果我使用的是NumPy的C API(特别PyArray_DATA是NumPy数组中的宏),那么从多个并发线程调用它会有潜在的后果吗?

请注意,我仍将拥有GIL,而不是通过NumPy的线程支持发布它.此外,即使NumPy不保证线程安全,但PyArray_DATA在实践中是线程安全的,这对我来说已经足够了.

我在Linux上运行带有NumPy 1.3.0的Python 2.6.6.

ide*_*ide 7

在这里回答我自己的问题,但在深入研究NumPy 1.3.0的源代码后,我相信答案是:是的,PyArray_DATA是线程安全的.

  1. PyArray_DATA 在ndarrayobject.h中定义:

    #define PyArray_DATA(obj) ((void *)(((PyArrayObject *)(obj))->data))
    
    Run Code Online (Sandbox Code Playgroud)
  2. PyArrayObject结构类型在同一文件中定义; 感兴趣的领域是:

    char *data;
    
    Run Code Online (Sandbox Code Playgroud)

    所以现在,问题是data从多个线程访问是否安全.

  3. 从头开始创建一个新的NumPy数组(即,不从现有数据结构派生它)将NULL数据指针传递给PyArray_NewFromDescrarrayobject.c中定义的数据指针.

  4. 这会导致PyArray_NewFromDescr调用PyDataMem_NEW以便为PyArrayObject的data字段分配内存.这只是malloc的一个宏:

    #define PyDataMem_NEW(size) ((char *)malloc(size))
    
    Run Code Online (Sandbox Code Playgroud)

总之,它PyArray_DATA是线程安全的,只要NumPy数组是单独创建的,就可以安全地从不同的线程写入它们.