我正在包装一个执行阻塞操作(选择)然后处理传入消息的 C 函数。我的理解是,当 C 函数将要阻塞时,在允许其他线程运行的同时调用它的正确方法是:
Py_BEGIN_ALLOW_THREADS
blocking_function();
Py_END_ALLOW_THREADS
但是,碰巧这个函数将回调指针作为参数。在处理由 C 函数预处理的传入消息时调用此回调。我已成功地将此回调包装在一个调用 PyEval_CallObject()
的函数中,从而允许我向它传递一个 Python 回调。
现在我正在添加线程支持,我想知道是否可以同时:
- 在调用此阻塞操作之前释放 GIL。
- 让这个阻塞操作安全地回调到 python 解释器中。
这会导致问题吗?如果是这样,是否有解决办法?
谢谢。
最佳答案
我几个月前用过这些API函数,现在的内存有些模糊,但我相信这段代码会解决你的问题。我假设版本 2.x(3.x 可能不同):
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
/* Make your call to PyEval_CallObject() here (and any other PY API calls). */
PyGILState_Release(gstate);
(以上内容摘自:Python C/API docs)
这基本上是 Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS 的倒数 宏。在这些函数中,您发布了 GIL,但在 PyGILState 函数中,您获得了 GIL。
关于python - 是否可以在阻塞并可能回调 Python 的 C 函数之前释放 GIL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5159040/