Python “多处理”与“并发”中的最大工作线程数`

Python “多处理”与“并发”中的最大工作线程数`,python,multiprocessing,concurrent.futures,Python,Multiprocessing,Concurrent.futures,在Python3.8中,concurrent.futures.ProcessPoolExecutor已更新,以将Windows上可使用的最大工作进程数限制为61。关于原因,请参见和,但据我所知: 在Windows上,multiprocessing调用Windows API函数WaitForMultipleObjects,该函数用于等待进程完成。它最多可以等待63个对象,少于结果队列读取器和线程唤醒读取器,因此限制为61个。(即Windows使用每个进程一个线程来跟踪进程) (另见) 然而,多

在Python3.8中,
concurrent.futures.ProcessPoolExecutor
已更新,以将Windows上可使用的最大工作进程数限制为61。关于原因,请参见和,但据我所知:

  • 在Windows上,
    multiprocessing
    调用Windows API函数
    WaitForMultipleObjects
    ,该函数用于等待进程完成。它最多可以等待63个对象,少于结果队列读取器和线程唤醒读取器,因此限制为61个。(即Windows使用每个进程一个线程来跟踪进程)
(另见)

然而,
多处理
仍然使用
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的池大小都不可靠。

非常感谢!我同意。这是一个有趣的“问题”,因为我不确定为什么没有相应地调整
多处理池。