我需要从我的C代码调用一个Python函数。 它工作得很好,但是当我想并行化时,它就崩溃了。 请参阅以下最小C代码:
#include <Python.h>
#include <stdio.h>
int main(void)
{
double Z = 1.;
double k = 1.;
double l = 1.;
double eta = -Z/k;
Py_Initialize();
PyObject* pName = PyString_FromString("mpmath");
PyObject* pModule = PyImport_Import(pName);
PyObject* pFunc = PyObject_GetAttrString(pModule, "coulombf");
PyObject* pl = PyFloat_FromDouble(l);
PyObject* peta = PyFloat_FromDouble(eta);
int i;
#pragma omp parallel for private(i)
for(i=0; i<10000; i++)
{
double r = 0.01*i;
PyObject* prho = PyFloat_FromDouble(k*r);
PyObject* pArgs = PyTuple_Pack(3, pl, peta, prho);
PyObject* pValue = PyObject_CallObject(pFunc, pArgs);
double value = PyFloat_AsDouble(pValue);
printf("r=%.2f\tf=%.6f\n",r,value);
}
Py_Finalize();
return 0;
}
让我们将这个文件命名为testPython.c
,您可以用gcc -fopenmp testPython.c -o testPython -I/usr/include/python2.7 -L/usr/lib64/python2.7/config -lpython2.7
编译它。在
现在用./testPython
运行它,会看到这样的错误:Fatal Python error: GC object already tracked
。(有时,错误信息不同。)
但是如果您编译它时不使用-fopenmp
,那么这个程序可以完美地工作。在
我怎样才能克服这个问题?谢谢!在
编辑:
正如Natecat、johnbollinger和Olaf所回答的那样,多线程处理不太可能加快处理速度,但多处理确实可以加快计算速度。纯python脚本如下所示:
^{pr2}$但是在C语言中怎么做呢?我还没找到路。在
@Natecat的回答基本上是对的,如果在细节和细微差别上有点欠缺的话。The docs of Python's C API给出一个更完整的图片。假设这是您正在使用的Python实现,您需要注意以下几点:
以及
注意:OpenMP就是这样。在
为了允许多个OpenMP线程安全地对同一个CPython解释器进行并发调用,您必须实现该模式,但是您不太可能从并行化中获得太多好处,因为各种OpenMP线程将在很大程度上被阻止并发运行。在
在python中不可能有任何类型的真正的多线程(例如在一个进程中使用多个系统线程),至少在最常见的python实现中是不可能的。您既可以不使用任何类型的并行化,也可以切换到没有GIL的实现。以下是一篇关于这个主题的更多信息的文章:https://wiki.python.org/moin/GlobalInterpreterLock
相关问题 更多 >
编程相关推荐