是否有可能在阻止并可能回调为Python的C函数之前释放GIL?

Ste*_*eve 4 python gil python-multithreading python-bindings

我正在包装一个执行阻塞操作(选择)的C函数,然后处理传入的消息.我的理解是,当一个C函数要阻塞时,在允许其他线程运行的同时调用它的正确方法是:

Py_BEGIN_ALLOW_THREADS                                                  
blocking_function();
Py_END_ALLOW_THREADS
Run Code Online (Sandbox Code Playgroud)

但是,它发生此函数将回调指针作为参数.在处理由C函数预处理的传入消息时调用此回调.我已经成功地将这个回调包装在一个调用的函数中PyEval_CallObject(),允许我传递一个Python回调.

现在我正在添加线程支持,我想知道是否可以同时:

  • 在调用此阻止操作之前释放GIL.
  • 让这个阻塞操作安全地回调到python解释器.

这会导致问题吗?如果是这样,有办法吗?

谢谢.

dap*_*wit 7

几个月前我使用过这些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);
Run Code Online (Sandbox Code Playgroud)

(以上摘自:Python C/API文档)

这基本上与Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS宏相反.在那些中,你释放GIL,但在PyGILState函数中你获得了GIL.