为啥在windows上使用python多处理时打印三遍?

Posted

技术标签:

【中文标题】为啥在windows上使用python多处理时打印三遍?【英文标题】:Why print three times when using python multiprocessing on windows?为什么在windows上使用python多处理时打印三遍? 【发布时间】:2021-05-23 17:10:33 【问题描述】:

考虑以下示例代码:

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 也必须定义了 3 次,并且导入和函数定义也可能重复了 3 次。这是浪费时间和资源,我不知道为什么windows上的设计是这样的。

好的,面对事实,我是否应该定义所有变量并将所有计算移到if __name__=="__main__" 之外以避免资源浪费? BTW,把函数定义移到里面会报错。

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

所以,是的,您必须将不希望新进程在全局空间之外执行的代码移动。一般而言,在全局空间中定义函数不会造成真正的危害,而且将子进程未使用的每个函数都移动到if 块内会太尴尬。

【讨论】:

以上是关于为啥在windows上使用python多处理时打印三遍?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在windows上调用多处理模块的函数时python可执行文件会打开新的窗口实例

为啥python在多行中打印一个多位数字?

Python 多处理 - 为啥每个进程有这么多线程?

为啥不能从 Kivy 终止这个 Python 多处理进程?

为啥我使用多处理/多线程的函数在 for 循环中使用时如此缓慢,但在循环之外却没有?

为啥在Python里推荐使用多进程而不是多线程