Python C 扩展是否像为 IO 任务一样为 CPU 任务发布 GIL?
Do Python C Extensions release the GIL for CPU tasks as they do for IO tasks?
Python C 扩展总是在进行 IO 系统调用时通过 Py_BEGIN_ALLOW_THREADS 释放 GIL。关于 C Extensions 是否为相对较长的 运行 CPU 绑定任务发布 GIL,我已经阅读了不同的意见。我读过 python 解释器中的 CPU 受 GIL 约束,但 C 扩展中的 CPU 通常会释放 GIL。我认为这样做是安全和高效的,只要 CPU 任务可以在具有细粒度锁定的临时变量中执行,并且在更新共享结构之前获取 GIL。
我在 Github 中搜索了 3.6 C 代码以查找 Py_BEGIN_ALLOW_THREADS
的所有实例。我可能错过了一些,但在我看来 Python C 扩展通常不会为 CPU 绑定任务发布 GIL。
Python C 扩展通常会像为 IO 任务一样为 CPU 任务释放 GIL?
这是我看到的他们为 CPU 任务发布 GIL 的唯一示例:
_hashlib.h 有一个宏 ENTER_HASHLIB,其注释表明它将在 CPU 消耗 hashlib 操作时释放 GIL。
sha3module.c 似乎在 CPU 操作之前允许线程。
_lzmamodule.c 似乎在 CPU 操作之前允许线程。
我找不到任何其他 CPU 释放 GIL 的调用(我肯定可能错过了一些,如果我错过了请告诉我)。
例如:
_bisectmoduel.c没有Py_BEGIN_ALLOW_THREADS.
_heapqmodule.c没有Py_BEGIN_ALLOW_THREADS.
_json.c没有Py_BEGIN_ALLOW_THREADS.
_csv.c没有Py_BEGIN_ALLOW_THREADS.
好吧,numpy
做到了,尽管他们用自己的宏包裹它 (NPY_BEGIN_ALLOW_THREADS
/ NPY_END_ALLOW_THREADS
)
根据docs:
This group is used to call code that may take some time but does not use any Python C-API calls. Thus, the GIL should be released during its calculation.
所以你可以释放GIL,但只有如果你不使用任何Python C-API调用。另一种说法是 if you do not access Python objects.
但是您链接的最后四个扩展模块中的代码填充 有 C-API 调用。因此,在那些不涉及 C-API 调用的模块中,可能没有用 C 完成足够的计算,因此值得释放和重新获取 GIL。
Python C 扩展总是在进行 IO 系统调用时通过 Py_BEGIN_ALLOW_THREADS 释放 GIL。关于 C Extensions 是否为相对较长的 运行 CPU 绑定任务发布 GIL,我已经阅读了不同的意见。我读过 python 解释器中的 CPU 受 GIL 约束,但 C 扩展中的 CPU 通常会释放 GIL。我认为这样做是安全和高效的,只要 CPU 任务可以在具有细粒度锁定的临时变量中执行,并且在更新共享结构之前获取 GIL。
我在 Github 中搜索了 3.6 C 代码以查找 Py_BEGIN_ALLOW_THREADS
的所有实例。我可能错过了一些,但在我看来 Python C 扩展通常不会为 CPU 绑定任务发布 GIL。
Python C 扩展通常会像为 IO 任务一样为 CPU 任务释放 GIL?
这是我看到的他们为 CPU 任务发布 GIL 的唯一示例:
_hashlib.h 有一个宏 ENTER_HASHLIB,其注释表明它将在 CPU 消耗 hashlib 操作时释放 GIL。
sha3module.c 似乎在 CPU 操作之前允许线程。
_lzmamodule.c 似乎在 CPU 操作之前允许线程。
我找不到任何其他 CPU 释放 GIL 的调用(我肯定可能错过了一些,如果我错过了请告诉我)。
例如:
_bisectmoduel.c没有Py_BEGIN_ALLOW_THREADS.
_heapqmodule.c没有Py_BEGIN_ALLOW_THREADS.
_json.c没有Py_BEGIN_ALLOW_THREADS.
_csv.c没有Py_BEGIN_ALLOW_THREADS.
好吧,numpy
做到了,尽管他们用自己的宏包裹它 (NPY_BEGIN_ALLOW_THREADS
/ NPY_END_ALLOW_THREADS
)
根据docs:
This group is used to call code that may take some time but does not use any Python C-API calls. Thus, the GIL should be released during its calculation.
所以你可以释放GIL,但只有如果你不使用任何Python C-API调用。另一种说法是 if you do not access Python objects.
但是您链接的最后四个扩展模块中的代码填充 有 C-API 调用。因此,在那些不涉及 C-API 调用的模块中,可能没有用 C 完成足够的计算,因此值得释放和重新获取 GIL。