2016-12-11 32 views
1

Python C APIの学習プロセスとして、tbb parallel_forに渡されたファンクタ内のPython関数を呼び出そうとしています。 関数を呼び出す操作で、Pythonプロセスのインスタンスがクラッシュします。 スレッドセーフではありません。私はリストから項目を取得し、関数の引数として渡された項目を持つPython関数を呼び出します。最後に、私はその項目をリストに戻しました。私は間違って何をしたのですか?Python C、tbb、複数のスレッドから関数を呼び出す

答えて

1

C++からPython関数を呼び出すときにグローバルインタープリタロック(GIL)を取得するのを忘れた可能性があります。例えば、を使ってPython implements thisため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。より高速な機能を作り、彼らはコンパイルされた関数からGILを取り除くように並列に実行するためにPythonの機能を有効に両方のNumbaの@cfunc(nopython=True)デコレータとCythonのnogil属性を使用することを含んで考慮すべき

その他のオプション。

関連する問題