2009-10-16 30 views
6

我有一個使用C++編寫的庫,使用SWIG進行封裝,並在Python中使用。通常有一個方法很少的課程。問題是調用這些方法可能會很費時 - 它們可能會掛起我的應用程序(調用這些方法時GIL不會被釋放)。所以我的問題是:在C++代碼中釋放Python GIL

這些方法調用釋放GIL最簡單的方法是什麼?

(我明白,如果我用一個C庫,我可以用一些額外的C代碼把這個包,但在這裏我使用C++和類)

回答

1

您可以使用相同的API調用爲C.沒有區別。包含「python.h」並調用appoproate函數。

此外,請參閱SWIG是否沒有類型映射表或指示GIL不保留用於特定功能的東西。

5

沒有任何想法是什麼痛飲是我會嘗試反正答案:)

使用這樣的釋放/收購GIL:

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

    ~GILReleaser() { 
     PyEval_RestoreThread(save); 
    } 

    PyThreadState* save; 
}; 

而在的代碼塊你選擇,使用RAII發佈/收購GIL:

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

謝謝,你救了我一些時間。 – Ellioh 2014-02-05 13:29:13

5

真正的問題是,SWIG未記錄好(我看到提示,使用更新日誌搜索;))。

好吧,我發現我可以在痛飲做內聯函數和使用宏來釋放/收購GIL,它看起來像這樣:

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

此功能並不存在於原來的C++,但在可python模塊。這(幾乎)正是我想要的。 (我想要的是包裝像Python裝飾的原始方法)

+0

使用Henrik's。這是正確的,但是不好的C++實踐。在釋放GIL之後,我也有一次從字典中提取數據的崩潰,所以我通常不會在GIL版本和重新獲取之間使用python.h中的任何函數。 – 2015-06-03 13:10:15