Python C,tbb,从多个线程调用一个函数

时间:2016-12-11 18:10:56

标签: python c++ c tbb

作为Python C API的学习过程,我试图在传递给tbb parallel_for的functor中调用Python函数。 调用该函数的操作崩溃了Python进程的实例。 我没有做任何不线程安全的事情。我从列表中获取项目然后我调用Python函数,并将项目作为参数传递给函数。最后,我将项目设置回列表。什么提示我做错了什么?

1 个答案:

答案 0 :(得分:1)

当您从C ++调用Python函数时,很可能忘记抓取Global Interpreter Lock(GIL)。例如,使用implements this的Python 的TBB模块:

class PyCaller : public swig::SwigPtr_PyObject {
public:
  using swig::SwigPtr_PyObject::SwigPtr_PyObject; // gets constructors

  void operator()() const {
    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
    PyObject* r = PyObject_CallFunctionObjArgs((PyObject*)*this, NULL);
    if(r) Py_DECREF(r);
    SWIG_PYTHON_THREAD_END_BLOCK;
  }
};

// Usage:
tbb::task_group tg;
void enqueue( PyObject *c ) {
    tg.run( PyCaller(c) );
}

您可以看到SWIG如何实现它 - here

要考虑的其他选项包括使用Numba的@cfunc(nopython=True)装饰器和Cython的nogil属性,这些属性可以使函数更快并使Python的函数能够并行运行他们从已编译的函数中删除GIL。