Windows 上的 Multiprocessing.pool.Pool:CPU 限制为 63?
Posted
技术标签:
【中文标题】Windows 上的 Multiprocessing.pool.Pool:CPU 限制为 63?【英文标题】:Multiprocessing.pool.Pool on Windows: CPU limit of 63? 【发布时间】:2021-03-22 22:55:24 【问题描述】:当使用超过 63 个内核的 python 的 multiprocessing.pool.Pool 时,我得到一个ValueError
:
from multiprocessing.pool import Pool
def f(x):
return x
if __name__ == '__main__':
with Pool(70) as pool:
arr = list(range(70))
a = pool.map(f, arr)
print(a)
输出:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Users\fischsam\Anaconda3\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\fischsam\Anaconda3\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\fischsam\Anaconda3\lib\multiprocessing\pool.py", line 519, in _handle_workers
cls._wait_for_updates(current_sentinels, change_notifier)
File "C:\Users\fischsam\Anaconda3\lib\multiprocessing\pool.py", line 499, in _wait_for_updates
wait(sentinels, timeout=timeout)
File "C:\Users\fischsam\Anaconda3\lib\multiprocessing\connection.py", line 879, in wait
ready_handles = _exhaustive_wait(waithandle_to_obj.keys(), timeout)
File "C:\Users\fischsam\Anaconda3\lib\multiprocessing\connection.py", line 811, in _exhaustive_wait
res = _winapi.WaitForMultipleObjects(L, False, timeout)
ValueError: need at most 63 handles, got a sequence of length 72
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69]
该程序似乎运行良好;结果正是我所期望的。我可以忽略ValueError
吗?
背景:我用谷歌搜索了这个问题,它似乎与 Windows 上的 python 限制有关 (_winapi.WaitForMultipleObjects
);参见例如here。建议的解决方法是将使用的内核数限制为 63。这并不令人满意,因为我想在我的服务器上使用 100 多个内核。我真的需要限制核心吗?为什么?有解决办法吗?
【问题讨论】:
【参考方案1】:有趣的是,当我使用 concurrent.futures
模块中的 PrcocessPoolExecutor(max_workers=70)
查看问题是否仍然存在时,我得到 ValueError: max_workers must be 并且程序在任何之前立即终止可以提交作业。 这强烈暗示了一个无法绕过的 Windows 限制。 但是,您的程序实际上从未终止,只是在遇到异常后挂起。在我的 8 核计算机上,如果我指定任何数量大于 60(不是 61 或 63)的工作人员,无论我使用 multiprocessing.Pool
还是 concurrent.futures.ProcessPoolExecutor
,它都会挂起。找出你的机器上允许它正常终止而不会产生异常的最大工作线程数并坚持下去。
from concurrent.futures import ProcessPoolExecutor
def f(x):
return x
if __name__ == '__main__':
with ProcessPoolExecutor(max_workers=70) as executor:
a = list(executor.map(f, range(70)))
print(a)
【讨论】:
感谢您的回答。我了解建议是使用多个可以正常工作而不会导致异常的 CPU。然而,我的实际问题是,使用更多 CPU 可能会出现什么问题以及原因。也许我可以忍受这些缺点。你有什么见解吗? 正如我所指出的,当我使用超过 60 个 CPU 时,我的程序永远不会终止。我认为这是一个主要缺点。然而,对于每个人来说(chacun à son goût)。此外,即使您指定了超过 60 个,如果 Python 不是为使用这些内核而设计的,那么是什么让您认为您实际上在使用额外的内核? 我可以在任务管理器中看到生成了多少进程,使用了多少CPU。我可以忍受必须手动终止程序,因为我目前没有广泛部署它。但是,根据您的评论,我发现上下文管理器的退出块未正确执行。我可能会继续朝这个方向搜索。以上是关于Windows 上的 Multiprocessing.pool.Pool:CPU 限制为 63?的主要内容,如果未能解决你的问题,请参考以下文章
Windows Server 2012 R2 上的 Windows 服务 PlatformNotSupportedException 上的 WCF