生成过程中的静态变量未初始化
Static variables in spawn processes are not initialised
对我来说很奇怪,“spawn”进程不复制class的静态变量,但是“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')
输出“分叉”:
[10, 10]
Done
输出“产卵”:
AttributeError: type object 'Foo' has no attribute 'static_var'
Python版本:3.8.5
我不知道如何用 spawn 来克服它(我也不完全明白为什么它不起作用)。 Spawn 进程启动自己的解释器并再次导入模块(和 classes?),这就是静态变量未初始化的原因?
如何通过 class?
传递变量
在多进程中,spwan 或 fork-server 工作进程是新的 python 进程。
所有内存状态都是新鲜的,if __name__ == "__main__:"
块未执行。
这个意义上的静态 class 变量不是静态的。
在 fork
工作进程中,复制了整个进程内存,因此可能复制了 class 变量,但一个进程中的任何更改都不会影响其他进程。
两种可能的解决方案:
- 修改任务函数和参数,使任务是独立的,不依赖于非静态环境。
- 使用
ProcessPoolExecutor
中的 initializer
参数正确设置静态变量。
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
对我来说很奇怪,“spawn”进程不复制class的静态变量,但是“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')
输出“分叉”:
[10, 10]
Done
输出“产卵”:
AttributeError: type object 'Foo' has no attribute 'static_var'
Python版本:3.8.5
我不知道如何用 spawn 来克服它(我也不完全明白为什么它不起作用)。 Spawn 进程启动自己的解释器并再次导入模块(和 classes?),这就是静态变量未初始化的原因? 如何通过 class?
传递变量在多进程中,spwan 或 fork-server 工作进程是新的 python 进程。
所有内存状态都是新鲜的,if __name__ == "__main__:"
块未执行。
这个意义上的静态 class 变量不是静态的。
在 fork
工作进程中,复制了整个进程内存,因此可能复制了 class 变量,但一个进程中的任何更改都不会影响其他进程。
两种可能的解决方案:
- 修改任务函数和参数,使任务是独立的,不依赖于非静态环境。
- 使用
ProcessPoolExecutor
中的initializer
参数正确设置静态变量。
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