多线程调用NumPy C API函数的影响是什么?
这件事有点风险,我知道全局解释器锁(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
是线程安全的。
PyArray_DATA
是在ndarrayobject.h文件中定义的:#define PyArray_DATA(obj) ((void *)(((PyArrayObject *)(obj))->data))
PyArrayObject这个结构类型也是在同一个文件中定义的;我们关注的字段是:
char *data;
所以现在的问题是,从多个线程访问
data
是否安全。从头创建一个新的NumPy数组(也就是说,不是从已有的数据结构派生出来的)时,会将一个
NULL
数据指针传递给PyArray_NewFromDescr
,这个函数是在arrayobject.c中定义的。这会导致
PyArray_NewFromDescr
调用PyDataMem_NEW
来为PyArrayObject的data
字段分配内存。这个其实就是malloc的一个宏:#define PyDataMem_NEW(size) ((char *)malloc(size))
总之,PyArray_DATA
是线程安全的,只要NumPy数组是单独创建的,就可以安全地从不同的线程写入它们。