gpt4 book ai didi

c++ - 解释 Python 扩展多线程

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:40:43 26 4
gpt4 key购买 nike

Python 解释器有一个全局解释器锁,我的理解是扩展必须在多线程环境中获取它。但是Boost.Python HOWTO page表示扩展函数必须释放 GIL 并在退出时重新获取它。

我不想在这里猜测,所以我想知道在以下场景中GIL锁定模式应该是什么:

  1. 扩展是从 python 调用的(大概是在 python 线程中运行)。
  2. 并且扩展的后台线程回调到 Py_* 函数。

最后一个问题是,为什么链接文档说应该发布并重新获取 GIL?

最佳答案

每当 Python 解释字节码时,GIL 就会被当前运行的线程占用。在它设法获取 GIL 之前,其他 Python 线程都不能运行。

当解释器调用 native 代码时,该代码有两个关于 GIL 的选项:

  1. 它什么也做不了。
  2. 它可以在工作时释放 GIL,然后在返回 Python 之前重新获取它

如果 native 代码对 Python 的运行时进行大量调用,它应该选择选项 1:除非您拥有 GIL,否则您永远无法安全地调用 Python 的运行时(有一些异常(exception),例如如果您进行调用以获取 GIL,则没有它)。

如果 native 代码做了很多不以任何方式涉及 Python 的工作,那么您可以使用选项 2:一旦您发布 GIL,Python 将能够安排另一个 Python 线程,从而获得一些并行性。如果您不释放 GIL,那么在您的 Boost 代码运行时,Python 的其他线程都无法执行:这就是文档告诉您释放并重新获取 GIL 的原因。

如果你这样做,那么在你释放 GIL 之前或重新获取它之后,你必须小心地访问 Py_* 函数。这可能意味着您必须制作数据的本地拷贝,因为在发布 GIL 时您无法安全地访问 Python 数据类型,例如列表或字典元素。

如果您的 Boost 代码需要在释放 GIL 时回调到 Python,那么您需要获取 GIL,进行调用,然后释放 GIL。尽量避免从不是由 Python 创建的线程进行此类调用,因为它们需要额外的工作才能获得 GIL。

关于c++ - 解释 Python 扩展多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2825362/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com