为什么在 windows 上使用 python 多处理时打印三次?

Why print three times when using python multiprocessing on windows?

考虑以下示例代码:

from multiprocessing import Pool


def f(k):
    return k*k


ks = [1, 2, 3]
print("Hello")

if __name__ == '__main__':
    pool = Pool(2)
    k2 = pool.map(f, ks)
    pool.close()
    pool.join()
    print(k2)

在 windows 上,输出为:

Hello
Hello
Hello
[1, 4, 9]

这又奇怪又丑陋,不是我所期望的。

Linux 上的相同代码,输出为:

Hello
[1, 4, 9]

这是我所期望的。

为什么 windows 上有三个 print?我认为以同样的方式, ks 也必须被定义三次,也许导入和函数定义也重复了三次。这是浪费时间和资源,我不知道为什么windows上的设计是这样的。

OK,面对现实,我是不是应该定义所有的变量,把if __name__=="__main__"外面的计算全部移到里面,避免资源浪费?顺便说一句,将函数定义移到里面会导致错误。

Linux支持fork,一种可以在代码中的任意位置将一个进程一分为二的操作。

Windows不支持fork,创建子进程比较复杂。数据必须序列化,程序必须在某种程度上(重新)执行(模块级别的代码)。

在 Windows 和其他使用 spawn 而不是 fork 创建新进程的平台上,新进程的执行从 top 的程序,这正是创建进程的代码必须在 if __name__=="__main__": 块内的原因。如果不是,那么新进程将递归地创建一个新进程 ad infinitum.

所以,是的,您必须将不希望新进程在全局 space 之外执行的代码移动。一般来说,在全局 space 中定义 函数不会造成真正的伤害,将子进程未使用的每个函数移动到 if块。