我正在用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函数采用类似"abcd"
的python字符串,进行大量计算。
然后返回python中的字符串列表,例如["123","qwer","xyz"]
。
foo
函数不会创建任何线程。
由于a_very_computation_function
可能需要很长时间。我应该在执行GIL期间将其释放吗?
从PyObject
读取内容是否需要受到GIL保护(在“确保”和“发布”之内)?
是否需要保护生成新的PyObject
不受GIL的保护?
是否需要保护呼叫PyErr_SetString
不受GIL的侵害?
我应该在哪里准确添加PyGILState_Ensure
和PyGILState_Release
?