为什么 GIL 不同步 Python 线程,这些线程是 DLL 中的 运行 本机 C++ 代码?
Why GIL is not synchrionizing Python threads that are running native C++ code inside a DLL?
我开发了一个简单的多线程 Python 应用程序 (Python 3.7) 以在 8 个线程中调用 8 个不同的计算密集型任务。这些任务可以是 Python 代码,也可以是嵌入在 DLL 中并可通过 ctypes 包访问的 C++ 代码。我是运行在Windows上的8核机器上做实验。
奇怪的是,当所有线程都调用Python代码时,似乎只有一个线程在特定时间处于活动状态,CPU利用率约为12.5%。但是在 DLL 中调用 C++ 代码时,整个内核都被使用,CPU 利用率为 100%。
现在的问题是,为什么 GIL(全局解释器锁)不同步调用本机 C++ 代码的 Python 线程? ctypes实现是否在调用原生C++代码时释放GIL?
编辑 1: 本机 C++ DLL 中没有使用像 Py_BEGIN_ALLOW_THREADS 这样的宏。
来自 [Python 3]: ctypes - Loading shared libraries(重点 是我的;感谢@user2357112 指出这个非常明确的引用(比我最初发布的要好):
The Python global interpreter lock is released before calling any function exported by these libraries, and reacquired afterwards.
您还可以在同一页面上以其他形式找到此语句(检查 PyDLL、CFUNCTYPE)。
有一些方法可以绕过 GIL 限制:
将 threading 模块用法替换为 multiprocessing ([Python 3]: multiprocessing - Process-based parallelism)。这是最常见的
封装可以并行执行的代码块在Py_BEGIN_ALLOW_THREADS / Py_END_ALLOW_THREADS.缺点是 .dll(s) 现在将依赖于 Python
我开发了一个简单的多线程 Python 应用程序 (Python 3.7) 以在 8 个线程中调用 8 个不同的计算密集型任务。这些任务可以是 Python 代码,也可以是嵌入在 DLL 中并可通过 ctypes 包访问的 C++ 代码。我是运行在Windows上的8核机器上做实验。
奇怪的是,当所有线程都调用Python代码时,似乎只有一个线程在特定时间处于活动状态,CPU利用率约为12.5%。但是在 DLL 中调用 C++ 代码时,整个内核都被使用,CPU 利用率为 100%。
现在的问题是,为什么 GIL(全局解释器锁)不同步调用本机 C++ 代码的 Python 线程? ctypes实现是否在调用原生C++代码时释放GIL?
编辑 1: 本机 C++ DLL 中没有使用像 Py_BEGIN_ALLOW_THREADS 这样的宏。
来自 [Python 3]: ctypes - Loading shared libraries(重点 是我的;感谢@user2357112 指出这个非常明确的引用(比我最初发布的要好):
The Python global interpreter lock is released before calling any function exported by these libraries, and reacquired afterwards.
您还可以在同一页面上以其他形式找到此语句(检查 PyDLL、CFUNCTYPE)。
有一些方法可以绕过 GIL 限制:
将 threading 模块用法替换为 multiprocessing ([Python 3]: multiprocessing - Process-based parallelism)。这是最常见的
封装可以并行执行的代码块在Py_BEGIN_ALLOW_THREADS / Py_END_ALLOW_THREADS.缺点是 .dll(s) 现在将依赖于 Python