Я пишу код, учитывающий производительность, в C и обертываю параметр функции с Python C API и ctypes.
Я не совсем понимаю, что такое PyGILState_Ensure
.Что это защищает?Когда я должен заблокировать или отпустить GIL.
Например:
extern "C" DLL PyObject * foo(PyObject * capsule, PyObject *pystr) {
MyClass *pointer = PyCapsule_GetPointer(capsule, "MyClass");
string s = convert_python_string_to_std_string(pystr);
auto state = PyGILState_Ensure();
try {
vector<string> strs = a_very_computation_function(pointer, s);
PyGILState_Release(state);
PyObject *output = convert_std_string_to_python_string_list(strs);
return output
}
catch (std::exception e) {
PyErr_SetString(PyExc_RuntimeError, e.what());
PyGILState_Release(state);
return NULL;
}
}
В python ctypes оборачивает это следующим образом:
lib = cdll.LoadLibrary("mydll.dll")
lib.foo.argtypes = [ py_object, py_object ] #capsule, str
lib.foo.restype = py_object # [str]
Функция foo принимаетСтрока Python, как "abcd"
, сделать тяжелый расчет.затем возвращает список строк в языке Python, например, ["123","qwer","xyz"]
.
foo
функция НЕ создает поток.
Поскольку a_very_computation_function
может занять очень много времени.Я должен выпустить GIL во время его освобождения?
Нужно ли защищать материал для чтения из PyObject
от GIL (в пределах «обеспечивает» и «выпуск»)?
Создает ли новое PyObject
нужно ли защищать от GIL?
Нужно ли защищать вызывающих PyErr_SetString
от GIL?
Куда мне добавить PyGILState_Ensure
и PyGILState_Release
точно?