为什么在使用concurrent.futures.ProcessPoolExecutor()进行多进程处理时,会打印出多个相同的消息?

6

这个语句“我应该只出现一次”应该只出现一次。但我不明白为什么它会多出现3次……

很明显我的代码执行了3个额外的过程。但在这3个过程中只调用了funktion0()。为什么语句"我应该只出现一次"会在这额外的3个过程中被包含呢?有人能解释一下吗?

代码:

from datetime import datetime
#print(datetime.now().time())

from time import time, sleep
#print(time())
print("I should appear only once")
from concurrent import futures


def funktion0(arg0):
    sleep(arg0)
    print(f"ich habe {arg0} sek. gewartet, aktuelle Zeit: {datetime.now().time()}")

if __name__=="__main__":

    with futures.ProcessPoolExecutor(max_workers=3) as obj0:
        obj0.submit(funktion0, 5)
        obj0.submit(funktion0, 10)
        obj0.submit(funktion0, 15)
        obj0.submit(funktion0, 20)
        print("alle Aufgaben gestartet")

    print("alle Aufgaben erledigt")

预期输出:

I should appear only once
alle Aufgaben gestartet
ich habe 5 sek. gewartet, aktuelle Zeit: 18:32:51.926288
ich habe 10 sek. gewartet, aktuelle Zeit: 18:32:56.923648
ich habe 15 sek. gewartet, aktuelle Zeit: 18:33:01.921168
ich habe 20 sek. gewartet, aktuelle Zeit: 18:33:11.929370
alle Aufgaben erledigt

实际输出:

I should appear only once
alle Aufgaben gestartet
I should appear only once
I should appear only once
I should appear only once
ich habe 5 sek. gewartet, aktuelle Zeit: 18:32:51.926288
ich habe 10 sek. gewartet, aktuelle Zeit: 18:32:56.923648
ich habe 15 sek. gewartet, aktuelle Zeit: 18:33:01.921168
ich habe 20 sek. gewartet, aktuelle Zeit: 18:33:11.929370
alle Aufgaben erledigt

请标记您的问题为“Windows”,因为它可能仅与Windows相关。 - Jean-François Fabre
@Jean-FrançoisFabre已完成 - vostro.beta
1个回答

5
这是一个经典的Windows问题(在Windows上使用Python多进程时的RuntimeError),只是不那么戏剧化。
当你在Windows上使用多进程时,进程不是通过fork分叉而是通过一些巧妙的机制复制(因为Windows操作系统中不存在fork),以“模拟”fork,但并不准确,因为操作系统不允许(在Windows中复制fork()的最佳方法是什么?)。
因此,除非你用__name__ == "__main__"保护它,否则该语句会被打印出与进程数相同的次数。
(你可能可以通过将大多数import语句移动到那个范围内来加快工作人员的启动速度)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接