Python “多处理”与“并发”中的最大工作线程数`
在Python3.8中,Python “多处理”与“并发”中的最大工作线程数`,python,multiprocessing,concurrent.futures,Python,Multiprocessing,Concurrent.futures,在Python3.8中,concurrent.futures.ProcessPoolExecutor已更新,以将Windows上可使用的最大工作进程数限制为61。关于原因,请参见和,但据我所知: 在Windows上,multiprocessing调用Windows API函数WaitForMultipleObjects,该函数用于等待进程完成。它最多可以等待63个对象,少于结果队列读取器和线程唤醒读取器,因此限制为61个。(即Windows使用每个进程一个线程来跟踪进程) (另见) 然而,多
concurrent.futures.ProcessPoolExecutor
已更新,以将Windows上可使用的最大工作进程数限制为61。关于原因,请参见和,但据我所知:
- 在Windows上,
调用Windows API函数multiprocessing
,该函数用于等待进程完成。它最多可以等待63个对象,少于结果队列读取器和线程唤醒读取器,因此限制为61个。(即Windows使用每个进程一个线程来跟踪进程)WaitForMultipleObjects
多处理
仍然使用os.cpu\u count()
。它首先抛出一个值错误
,但随后继续,并使用100%的CPU内核。比如说,
Exception in thread Thread-N:
Traceback (most recent call last):
File "C:\Users\username\AppData\Local\Programs\Python\Python38\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\username\AppData\Local\Programs\Python\Python38\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\username\AppData\Local\Programs\Python\Python38\lib\multiprocessing\pool.py", line 519, in _handle_workers
cls._wait_for_updates(current_sentinels, change_notifier)
File "C:\Users\username\AppData\Local\Programs\Python\Python38\lib\multiprocessing\pool.py", line 499, in _wait_for_updates
wait(sentinels, timeout=timeout)
File "C:\Users\username\AppData\Local\Programs\Python\Python38\lib\multiprocessing\connection.py", line 879, in wait
ready_handles = _exhaustive_wait(waithandle_to_obj.keys(), timeout)
File "C:\Users\username\AppData\Local\Programs\Python\Python38\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 98
我的机器有96个核心。这个“错误”真的是错误吗?如果没有,我应该只使用多处理
模块而不是并发.futures
模块吗?该模块将我的CPU使用限制为61个内核
编辑:我怀疑这是一个错误,因为我假设
多进程
将继续等待抛出错误的进程完成。如果我不限制内核的数量,这种情况似乎会发生(程序只是在CPU使用率下降后挂起)。然而,我不确定它是否真的是。你的问题很好。查看代码,这似乎是一个无法恢复的错误。但在我看来,不可理解的是,ThreadPoolExecutor
中会有代码将Windows下的池大小限制为61,而不是对multiprocessing.pool
类强制执行。无论如何,用下面的程序检查应该很容易。如果未打印完成和挂起,我想说肯定存在问题,如果您使用的是多处理。pool
:
导入多处理
def工人(x):
返回x**2
def main():
池=多处理。池(96)
结果=pool.map(工作者,范围(96))
断言长度(结果)=96
pool.close()
pool.join()
打印('Done!')
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
但是您的程序挂起这一事实相当确定,上面的程序将挂起,我怀疑您甚至无法使用
assert
语句。无论如何,使用大于61的池大小都不可靠。非常感谢!我同意。这是一个有趣的“问题”,因为我不确定为什么没有相应地调整多处理池。