Releasing Python GIL while in C++ code

三世轮回 提交于 2019-12-04 21:27:23

问题


I've got a library written in C++ which I wrap using SWIG and use in python. Generally there is one class with few methods. The problem is that calling these methods may be time consuming - they may hang my application (GIL is not released when calling these methods). So my question is:

What is the simplest way to release GIL for these method calls?

(I understand that if I used a C library I could wrap this with some additional C code, but here I use C++ and classes)


回答1:


The real problem is that SWIG is not documented well (I saw hints to use changelog for searching ;) ).

Ok, I found out that I can do inline functions in SWIG and use macros to release/acquire GIL, it looks like this:

%inline %{
    void wrappedFunction(OriginalObject *o, <parameters>) {
    Py_BEGIN_ALLOW_THREADS
    o->originalFunction(<parameters>);
    Py_END_ALLOW_THREADS
}
%}

This function is not present in original C++, but available in python module. This is (almost) exactly what I wanted. (what I would like is to wrap original method like python decorator does)




回答2:


Not having any idea what SWIG is I'll attempt an answer anyway :)

Use something like this to release/acquire the GIL:

class GILReleaser {
    GILReleaser() : save(PyEval_SaveThread()) {}

    ~GILReleaser() {
        PyEval_RestoreThread(save);
    }

    PyThreadState* save;
};

And in the code-block of your choosing, utilize RAII to release/acquire GIL:

{
    GILReleaser releaser;
    // ... Do stuff ...
}



回答3:


You can use the same API call as for C. No difference. Include "python.h" and call the appoproate function.

Also, see if SWIG doesn't have a typemap or something to indicate that the GIL shuold not be held for a specific function.



来源:https://stackoverflow.com/questions/1576737/releasing-python-gil-while-in-c-code

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!