使用多线程函数ThreadPoolExecutor(),如果使用默认参数,则max_workers =None,参考源代码发现
if max_workers is None:
# Use this number because ThreadPoolExecutor is often
# used to overlap I/O instead of CPU work.
max_workers = (os.cpu_count() or 1) * 5
进一步:
max_workers = (os.cpu_count() or 1) * 5 的解释
但是为什么是乘以 5 呢?
os.cpu_count()
Return the number of CPUs in the system; return None if indeterminable.
# 返回系统中CPU的数目;如果不确定,则返回无。
print(os.cpu_count()) # 64
# 与多线程ThreadPoolExecutor 不同
# 实际上,多进程ProcessPoolExecutor(max_workers=60)最多能用60
# 本地查找设备管理器,处理器只有40个,没找到具体原因。
看这里https://bugs.python.org/issue26903
ProcessPoolExecutor(max_workers=64) crashes on Windows
我是max_workers=61就crashes了,使用ProcessPoolExecutor默认参数(max_workers=None)也是同样的错误。查ProcessPoolExecutor源码,
if max_workers is None:
self._max_workers = os.cpu_count() or 1
说明max_workers 实际上是64,也就是说61到64都会报如下错误。
Exception in thread QueueManagerThread:
...
ValueError: need at most 63 handles, got a sequence of length 63
print(max_workers) # 320
# 输出因个人电脑而异
print((None or 1) * 5) # 5
print((0 or 1) * 5) # 5
print((2 or 1) * 5) # 10