缓慢的未来.ProcessPoolExecutitor:如何改进



我试图理解为什么以下代码如此缓慢:

import threading
import time
import concurrent.futures
from datetime import datetime

def dump(txt):
print(f'[{datetime.now()}] ({threading.get_ident():05}) {txt}n', end='')

def sleep_(_):
dump('Start')
time.sleep(0.1)
dump('Stop')

def main(n=10, processes=10):
dump('before with')
with concurrent.futures.ProcessPoolExecutor(processes) as pool:
dump('before map')
tmp = list(pool.map(sleep_, range(n)))
dump('after map')
dump('after with')

if __name__ == '__main__':
main()

这就是结果:

[2020-10-17 23:34:12.822813] (07100) before with
[2020-10-17 23:34:12.824808] (07100) before map
[2020-10-17 23:34:21.409045] (14100) Start
[2020-10-17 23:34:21.414031] (15408) Start
[2020-10-17 23:34:21.414031] (20292) Start
[2020-10-17 23:34:21.415029] (18972) Start
[2020-10-17 23:34:21.416026] (13660) Start
[2020-10-17 23:34:21.416026] (10904) Start
[2020-10-17 23:34:21.417023] (18828) Start
[2020-10-17 23:34:21.418021] (18616) Start
[2020-10-17 23:34:21.504788] (01776) Start
[2020-10-17 23:34:21.509775] (14100) Stop
[2020-10-17 23:34:21.509775] (14100) Start
[2020-10-17 23:34:21.514761] (20292) Stop
[2020-10-17 23:34:21.514761] (15408) Stop
[2020-10-17 23:34:21.515760] (18972) Stop
[2020-10-17 23:34:21.516757] (13660) Stop
[2020-10-17 23:34:21.516757] (10904) Stop
[2020-10-17 23:34:21.517754] (18828) Stop
[2020-10-17 23:34:21.518751] (18616) Stop
[2020-10-17 23:34:21.605519] (01776) Stop
[2020-10-17 23:34:21.610506] (14100) Stop
[2020-10-17 23:34:21.611503] (07100) after map
[2020-10-17 23:34:23.281562] (07100) after with

我在这里试图理解的是,为什么第一个过程需要将近9秒才能开始。为什么要花将近2秒才能清除它们?

这是一个windows系统(正在调试中(。当我正常运行它时,它需要+-0.5秒才能旋转和减速。

与同一系统上的Debian WSL相比:0.04秒的旋转速度&0.006秒才能减速。

这是正常行为吗?和/或如何改进?为什么会发生这种情况?

谢谢!

在Linux和其他类似Unix的操作系统上,进程是用fork系统调用创建的,该系统调用基本上会创建主进程的延迟副本(写时副本(。这是一个快速的操作。

Windows没有fork功能,因此必须通过启动一个新的解释器并执行完整的Python代码(除了最后受保护的if __name__ == '__main__':部分(来创建每个工作进程,以便在使用之前设置该进程。Python称之为";"产卵";方法。

自Python 3.8以来,spawn方法也是MacOS上的默认方法。

Windows没有与fork系统调用等效的方法来复制进程。这意味着在Windows中使用一个有10个工人的多处理池将创建10个新的python进程。

启动第一个进程不需要9秒,启动池中的所有10个进程,然后向第一个进程启动目标函数需要9秒。

相关内容

  • 没有找到相关文章

最新更新