Когда я должен позвонить PyGILState_Ensure? - PullRequest
0 голосов
/ 03 января 2019

Я пишу код, учитывающий производительность, в 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 точно?

...