ThreadPoolExecutor 如何利用 32 个 CPU 核心来执行 CPU 密集型任务

Ruf*_*fus 5 python multithreading gil python-3.x

来自ThreadPoolExecutor

在 version 3.8 中更改: max_workers 的默认值更改为 min(32, os.cpu_count() + 4)。此默认值为 I/O 绑定任务保留至少 5 个工作线程。它最多使用 32 个 CPU 核心来执行释放 GIL 的 CPU 密集型任务。它避免了在多核机器上隐式使用大量资源。

根据我对 GIL 的理解,基于线程的并发仅适用于 I/O 绑定任务。对于 CPU 密集型任务,基于线程的并发是不可能的,这意味着对于 CPU 密集型任务,GIL 仅强制单线程执行。我的理解似乎与 中的粗体行相矛盾ThreadPoolExecutor。我在这里误解了什么?

此外,什么是

释放GIL

意思是?CPU 密集型任务不会保留 GIL(除非它被抢占)吗?

这个答案来看,我怀疑这与

大部分时间都花在旨在发布 GIL 的外部库上(如 NumPy)

这是否意味着只要线程在某些专门设计的“旨在释放 GIL”的外部库中执行 CPU 密集型任务,CPU 密集型任务的基于线程的并发实际上是可能的?

hob*_*bbs 4

对,就是这样。由于 GIL 保护 python 解释器状态,因此如果库有大量不涉及访问 Python 变量或调用 Python 函数的工作要做,则可以释放锁。NumPy 就是这样一个可以经常执行此操作的库。