python - 是否可以在阻塞并可能回调 Python 的 C 函数之前释放 GIL?

标签 python gil python-multithreading python-bindings

我正在包装一个执行阻塞操作(选择)然后处理传入消息的 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/

相关文章:

python - 如何在 Django 1.10 中使用 `unaccent` 进行全文搜索?

python - 在某些情况下,Python 线程可以安全地操作共享状态吗?

c++ - 使用线程在python中调用多个c++函数

python - 多线程 Python 网络爬虫卡住了

python - 使用 Python 3 获取文件的杂音哈希

Python 3.x : User Input to Call and Execute a Function

python - 在 pymongo 的字典中包含 NumberInt

python - Python 中具有多个线程的多个进程

python - 线程顺序循环还是并发循环?

python - 在时间段 Y 内运行 X 个 Python 线程