ThreadPoolExecutor 如何利用 32 CPU 个内核执行 CPU 绑定任务
How does ThreadPoolExecutor utilise 32 CPU cores for CPU bound tasks
Changed in version 3.8: Default value of max_workers is changed to min(32, os.cpu_count() + 4). This default value preserves at least 5 workers for I/O bound tasks. It utilizes at most 32 CPU cores for CPU bound tasks which release the GIL. And it avoids using very large resources implicitly on many-core machines.
根据我对 GIL 的理解,基于线程的并发仅适用于 I/O 绑定任务。对于 CPU 绑定任务,基于线程的并发是不可能的,这意味着对于 CPU 绑定任务,GIL 只强制单线程执行。我的理解似乎与 ThreadPoolExecutor
中的粗线相矛盾。我在这里误解了什么?
此外,
which release the GIL
是什么意思? CPU 绑定任务不会保留 GIL(除非它被抢占)吗?
来自this answer,我怀疑这与
有关
spending most of its time in an external library designed to release the GIL (like NumPy)
这是否意味着 CPU 绑定任务的基于线程的并发实际上是可能的,前提是线程在一些专门设计的“旨在释放 GIL”的外部库中执行 CPU 绑定任务?
是的,没错。由于 GIL 保护 python 解释器状态,如果库有大量工作要做 不涉及访问 Python 变量或调用 Python 函数 。 可以经常这样做。
Changed in version 3.8: Default value of max_workers is changed to min(32, os.cpu_count() + 4). This default value preserves at least 5 workers for I/O bound tasks. It utilizes at most 32 CPU cores for CPU bound tasks which release the GIL. And it avoids using very large resources implicitly on many-core machines.
根据我对 GIL 的理解,基于线程的并发仅适用于 I/O 绑定任务。对于 CPU 绑定任务,基于线程的并发是不可能的,这意味着对于 CPU 绑定任务,GIL 只强制单线程执行。我的理解似乎与 ThreadPoolExecutor
中的粗线相矛盾。我在这里误解了什么?
此外,
which release the GIL
是什么意思? CPU 绑定任务不会保留 GIL(除非它被抢占)吗?
来自this answer,我怀疑这与
有关spending most of its time in an external library designed to release the GIL (like NumPy)
这是否意味着 CPU 绑定任务的基于线程的并发实际上是可能的,前提是线程在一些专门设计的“旨在释放 GIL”的外部库中执行 CPU 绑定任务?
是的,没错。由于 GIL 保护 python 解释器状态,如果库有大量工作要做 不涉及访问 Python 变量或调用 Python 函数 。