一尘不染

Python多处理Linux Windows的区别

linux

这段代码在linux上执行,但是抛出AttributeError:类型对象“ T”在Windows上没有属性“ val”,为什么?

from multiprocessing import Process
import sys

class T():
    @classmethod
    def init(cls, val):
        cls.val = val

def f():
    print(T.val)

if __name__ == '__main__':
    T.init(5)

    f()

    p = Process(target=f, args=())
    p.start()

阅读 296

收藏
2020-06-07

共1个答案

一尘不染

Windows缺少fork()系统调用,该系统调用重复了当前过程。这有很多含义,包括Windows多处理文档页面上列出的含义。进一步来说:

请记住,如果在子进程中运行的代码尝试访问全局变量,则它看到的值(如果有)可能与调用Process.start时父进程中的值不同。

在内部,python通过从头开始一个新进程并告诉它再次加载所有模块,从而在Windows上创建了一个新进程。因此,您在当前流程中所做的任何更改都不会显示。

在您的示例中,这意味着在子进程中,将加载您的模块,但是该if __name__ == '__main__'部分将不会运行。因此T.init将不会被调用,并且T.val将不存在,因此您将看到错误。

另一方面,在POSIX系统(包括Linux)上,流程创建使用fork,所有全局状态都保持不变。该子项带有所有内容的副本,因此它不必重新加载任何内容,并且将看到其副本T和的副本val

这也意味着在POSIX系统上,进程的创建要快得多,资源占用也要少得多,特别是因为“复制”使用写时复制来避免实际复制数据的开销。

使用多重处理时还有其他怪癖,请参阅python多重处理指南中详细说明。

2020-06-07