python - 多处理时如何让 Python 尊重可迭代字段?

标签 python multiprocessing iterable concurrent.futures non-static

如果这是一个愚蠢的问题,我深表歉意,但我还没有找到解决这个问题的优雅方法。基本上,当使用 concurent.futures 模块时,类的非静态方法看起来应该可以正常工作,我没有在该模块的文档中看到任何暗示它们无法正常工作的内容,并且该模块不会产生运行时出错 - 在许多情况下甚至会产生预期的结果!
但是,我注意到该模块似乎不尊重在父线程中对可迭代字段进行的更新,即使这些更新发生在启动任何子进程之前也是如此。这是我的意思的一个例子:

import concurrent.futures


class Thing:
    data_list = [0, 0, 0]
    data_number = 0

    def foo(self, num):
        return sum(self.data_list) * num

    def bar(self, num):
        return num * self.data_number


if __name__ == '__main__':
    thing = Thing()
    thing.data_list[0] = 1
    thing.data_number = 1

    with concurrent.futures.ProcessPoolExecutor() as executor:
        results = executor.map(thing.foo, range(3))
        print('result of changing list:')
        for result in results:
            print(result)

        results = executor.map(thing.bar, range(3))
        print('result of changing number:')
        for result in results:
            print(result)
我希望这里的结果是
result of changing list:
0
1
2
result of changing number:
0
1
2
但相反我得到
result of changing list:
0
0
0
result of changing number:
0
1
2
因此,出于某种原因,对于只是一个整数的字段,事情按预期工作,但对于作为列表的字段,则完全不像预期的那样。这意味着在调用子进程时不会尊重对列表所做的更新,即使对更简单字段的更新也是如此。我已经用 dicts 尝试过这个问题以及同样的问题,我怀疑这是所有可迭代对象的问题。
有什么方法可以使这项工作按预期进行,允许子进程尊重对可迭代字段的更新?像这样半实现非静态方法的多处理似乎很奇怪,但我希望我只是错过了一些东西!

最佳答案

这个问题与“尊重可迭代字段”无关,但这是一个相当微妙的问题。在您的主要流程中,您有:

thing.data_list[0] = 1 # first assignment
thing.data_number = 1 # second assignmment
而不是:
Thing.data_list[0] = 1 # first assignment
Thing.data_number = 1 # second assignment
就第一个分配而言,没有任何实质性区别,因为在任何一个版本中,您都不是在修改类属性,而是在列表中恰好被类属性引用的元素。换句话说,Thing.data_list仍然指向同一个列表;这个引用没有改变。这是一个重要的区别。
但是在您的代码版本的第二次分配中,您实际上已经通过实例的 self 修改了类属性。引用。当您这样做时,您将创建一个具有相同名称 data_number 的新实例属性。
你的类(class)成员函数foobar正在尝试通过 self 访问类属性. Thing例如,thingThing 时,将被腌制到新地址空间但在新地址空间中未腌制,默认情况下,将创建新的类属性并将其初始化为其默认值,除非您添加特殊的腌制规则。但是实例属性应该是传输成功的,比如你新创建的data_number .这就是为什么“更改数字的结果:”会按您的预期打印出来,即您实际上正在访问实例属性 data_numberbar .
更改bar到以下内容,您将看到所有内容都将打印为 0 :
    def bar(self, num):
        return num * Thing.data_number

关于python - 多处理时如何让 Python 尊重可迭代字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67469233/

相关文章:

Python - 时间数据不匹配格式

windows - IBM API 的 Python 多处理错误(Q Experience)

Python 多处理线程在处理大量工作时从不加入

python - 为什么没有join()守护程序不退出

Java 迭代 Iterable<Text> 值并将它们添加到不同值的列表中

java - Java 迭代器的奇怪行为

python for 循环子图

python - 禁用有关 View 函数未返回响应的 Flask 警告?

python - 尝试使用 shopify python api 启动 session 时出现 500 内部服务器错误

java - 具有迭代器错误的Reducer