多线程调用NumPy C API函数的影响是什么?

7 投票
1 回答
1626 浏览
提问于 2025-04-16 08:04

这件事有点风险,我知道全局解释器锁(GIL)是并行处理的一个大障碍。不过,如果我在使用NumPy的C接口(特别是对NumPy数组使用PyArray_DATA宏),那么从多个同时运行的线程调用它会有什么潜在的后果呢?

需要注意的是,我仍然会持有GIL,并且不会通过NumPy的线程支持来释放它。此外,即使NumPy对线程安全没有保证,但如果PyArray_DATA在实际使用中是线程安全的,那对我来说就足够了

我在Linux上运行的是Python 2.6.6和NumPy 1.3.0。

1 个回答

7

我在这里回答我自己的问题,经过查看NumPy 1.3.0的源代码,我相信答案是:是的,PyArray_DATA是线程安全的。

  1. PyArray_DATA是在ndarrayobject.h文件中定义的:

    #define PyArray_DATA(obj) ((void *)(((PyArrayObject *)(obj))->data))
    
  2. PyArrayObject这个结构类型也是在同一个文件中定义的;我们关注的字段是:

    char *data;
    

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

  3. 从头创建一个新的NumPy数组(也就是说,不是从已有的数据结构派生出来的)时,会将一个NULL数据指针传递给PyArray_NewFromDescr,这个函数是在arrayobject.c中定义的。

  4. 这会导致PyArray_NewFromDescr调用PyDataMem_NEW来为PyArrayObject的data字段分配内存。这个其实就是malloc的一个宏:

    #define PyDataMem_NEW(size) ((char *)malloc(size))
    

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

撰写回答