简体   繁体   English

生成过程中的 Static 变量未初始化

[英]Static variables in spawn processes are not initialised

It is strange for me, that "spawn" process does not copy static variables of class, but with "fork" everything is ok.对我来说很奇怪,“spawn”过程不会复制 class 的 static 变量,但是使用“fork”一切正常。

Code:代码:

import typing as t
import multiprocessing as mp
from concurrent.futures import ProcessPoolExecutor


class Foo:
    static_var: int

    def __init__(self):
        pass


def func(foo_class: t.Type[Foo]):
    return foo_class.static_var


if __name__ == "__main__":
    # with ProcessPoolExecutor(mp_context=mp.get_context("fork")) as executor:
    with ProcessPoolExecutor(mp_context=mp.get_context("spawn")) as executor:
        foo_class = Foo
        foo_class.static_var = 10
        res = executor.map(func, [foo_class, foo_class])
        print(list(res))
    print('Done')

Output "fork": Output“叉子”:

[10, 10]
Done

Output "spawn": Output“产卵”:

AttributeError: type object 'Foo' has no attribute 'static_var'

Python version: 3.8.5 Python 版本:3.8.5

I have no idea how to overcome it with a spawn (and I do not totally understand why it does not work).我不知道如何通过生成来克服它(而且我不完全理解为什么它不起作用)。 Spawn process starts own interpreter and import modules again (and classes?), that is why static variables are not initialised?生成过程再次启动自己的解释器和导入模块(和类?),这就是为什么 static 变量没有初始化的原因? How it is possible to pass a variable via a class?如何通过 class 传递变量?

In multiprocessing, the spwan or fork-server worker processes are new python processes.在多处理中, spwanfork-server工作进程是新的 python 进程。
All memory states are fresh and the if __name__ == "__main__:" block is not executed.所有 memory 状态都是新鲜的,并且if __name__ == "__main__:"块未执行。 The static class variable in this sense is not static.在这个意义上,static class 变量不是 static。

In the fork worker processes, the whole process memory is copied so the class variable is likely copied but any change in one process do not affect other processes.fork工作进程中,整个进程 memory 被复制,因此 class 变量可能被复制,但一个进程中的任何更改都不会影响其他进程。

Two possible solutions:两种可能的解决方案:

  • Modify the task function and arguments such that the task is self-contained and do not depend on non-static environment.修改任务 function 和 arguments 使得任务是自包含的并且不依赖于非静态环境。
  • Use the initializer argument in ProcessPoolExecutor to set up the static variable correctly.使用ProcessPoolExecutor中的initializer参数正确设置 static 变量。
def worker_initializer():
    foo_class = Foo
    foo_class.static_var = 10

with ProcessPoolExecutor(
    initializer=worker_initializer,
    mp_context=mp.get_context("spawn")
) as executor:
    pass

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM