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

Python C, tbb, calling a function from multiple threads

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

很可能是您在从 C++ 调用 Python 函数时忘记获取全局解释器锁 (GIL)。例如,Python implements this using :

的 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) decorator and Cython's nogil 属性,这既可以使函数更快,又可以使 Python 的函数与 运行 并行,因为它们从编译函数中删除了 GIL。