4

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

Py_BEGIN_ALLOW_THREADS                                                  
blocking_function();
Py_END_ALLOW_THREADS

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

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

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

这会引起问题吗?如果是这样,有没有办法解决它?

谢谢。

4

2 回答 2

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);

(以上摘自:Python C/API docs

这基本上与 Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS 宏相反。在这些函数中,您释放 GIL,但在 PyGILState 函数中,您获取 GIL。

于 2011-03-01T19:26:26.900 回答
1

如果我使用全局来存储 的结果PyEval_SaveThread,并在回调中使用它来调用PyEval_RestoreThread. 我只需要弄清楚如何通过回调的上下文指针更干净地将其传递给我的代码中的回调。

于 2011-03-01T19:24:18.067 回答