繁体   English   中英

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

[英]Static variables in spawn processes are not initialised

对我来说很奇怪,“spawn”过程不会复制 class 的 static 变量,但是使用“fork”一切正常。

代码:

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“叉子”:

[10, 10]
Done

Output“产卵”:

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

Python 版本:3.8.5

我不知道如何通过生成来克服它(而且我不完全理解为什么它不起作用)。 生成过程再次启动自己的解释器和导入模块(和类?),这就是为什么 static 变量没有初始化的原因? 如何通过 class 传递变量?

在多处理中, spwanfork-server工作进程是新的 python 进程。
所有 memory 状态都是新鲜的,并且if __name__ == "__main__:"块未执行。 在这个意义上,static class 变量不是 static。

fork工作进程中,整个进程 memory 被复制,因此 class 变量可能被复制,但一个进程中的任何更改都不会影响其他进程。

两种可能的解决方案:

  • 修改任务 function 和 arguments 使得任务是自包含的并且不依赖于非静态环境。
  • 使用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