当前位置: 首页 > 面试题库 >

为什么multiprocessing.Process在Windows和Linux上对于全局对象和函数参数的行为有所不同

商正诚
2023-03-14
问题内容

在Windows和Linux(两者均与python2.7一起)上运行时,以下代码具有不同的输出

'''import_mock.py'''
to_mock = None



'''test.py'''
import import_mock
from multiprocessing import Process

class A(object):
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3

    def __getstate__(self):
        print '__getstate__'
        return { 'a': self.a, 'b': self.b,
                 'c':0 }

def func():
    import_mock.to_mock = 1
    a = A()
    return a

def func1(a):
    print a.a, a.b, a.c
    print import_mock.to_mock


if __name__ == '__main__':
    a = func()
    p = Process(target=func1, args=(a,))
    p.start()
    p.join()

在Windows上,输出为:

__getstate__
1 2 0
None

这是我所期望的

在linux上,它是:

1 2 3
1

其中不克隆全局对象和传递的参数。

我的问题是为什么他们的行为有所不同?以及如何使linux代码的行为与Windows相同?


问题答案:

添加到@Blckknght的答案:在Windows上,每个进程都“从头开始”导入原始模块,而在Unix-
y系统上,只有主进程运行整个模块,而所有其他进程都会看到当时存在的fork()内容用于创建该模块。新流程(不,
不称fork()自己-multiprocessing内部人员在创建新流程时会调用它)。

详细为您import_mock

  • 在所有平台上,主进程调用func(),其设置import_mock.to_mock为1。

  • 在Unix-y平台上,这是所有新进程所看到的:fork()之后发生,因此1是所有新进程继承的状态。

  • 在Windows上,所有新进程都“从头开始”运行整个模块。因此,他们各自导入自己的全新版本的import_mock。只有主进程调用func(),因此只有主进程看到to_mock更改为1。所有其他进程看到最新None状态。

这都是预料之中的,并且第二次实际上很容易理解;-)

传递的过程a是微妙的,因为它更多地取决于multiprocessing实现细节。该实现 可能
从一开始就选择在所有平台上腌制参数,但事实并非如此,现在进行更改而又不破坏 某些 平台上的内容为时已晚。

由于写时复制的fork()语义,因此 不必Process()在Unix-
y系统上腌制参数,因此实现从来没有。但是,如果没有fork(),则必须在Windows上对其进行酸洗-实现也是如此。

在允许您spawn在所有平台上强制执行“ Windows实现”()的Python 3.4之前,没有机械方法来避免可能出现的跨平台意外情况。

但实际上,我很少为此感到困扰。 例如, 知道
多处理可能严重依赖于酸洗,因此我完全不了解使用酸洗技巧。传递A()实例时出现“问题”的唯一原因是您正在玩腌菜(通过覆盖默认值__getstate__())。



 类似资料:
  • 在请求中,用户可以发送值为的参数,我想确定这些参数是谁。 将这些值强制转换为模型,并将值赋予未与用户一起发送的空参数。 我正在尝试确定哪些参数保存值以防止它们在保存之前损坏我的整个数据记录。 谢谢!

  • 例如,我有: 有没有办法将和导出为全局函数,这样我就可以直接调用,而不是? 我的上下文是使用Rhino/Nashorn脚本引擎,我想注入一个提供全局函数的“全局”对象。

  • 问题内容: 您能解释下一个有趣的行为吗? 让我们转换为数组。 结果: 好,财产变成 让我们将此数组转换为对象。 结果: 是一个对象。 问题是: 为什么要成为新对象的私有财产(不是)?PHP如何知道该数组是一个对象? 如果我定义相等的数组: 然后将其转换为对象: 我将获得具有两个 公共 属性的对象,并且与预期的一样: 问题答案: 数组键包含一个标记,该标记应为类测试的私有属性。 将脚本输出与以下内容

  • 我知道这个问题以前在stackoverflow上被问过。然而,我还没有找到一个答案来实际测试服务,例如使用Postman。 我已经按照留档和我的服务是几乎相同的描述留档: 当我尝试使用Postman加热我的服务时,我得到了以下错误: org.springframework.web.multipart.多部分异常:当前请求不是多部分请求 在《邮递员》杂志上,我得到了如下回报 问题是:是否可以使用邮递

  • 问题内容: 在python中进行如下构造是有效的: 我想问一个函数指针被评估为True的逻辑是什么。 为什么在语言中插入这种构造? 问题答案: 在Python中有很多评估结果。从关于布尔运算符的文档中: 在布尔运算的上下文中,以及当控制流语句使用表达式时,以下值将解释为false:,,所有类型的数字零以及空字符串和容器(包括字符串,元组,列表,字典,集合和Frozensets)。所有其他值均解释为

  • null 只使用数据类型有什么特别的缺点吗? 使用数据类型代替数据类型有意义吗?