Python 模块属性更新未传播到Windows上的子进程

Python 模块属性更新未传播到Windows上的子进程,python,multiprocessing,contextmanager,Python,Multiprocessing,Contextmanager,我遇到一些与Windows上的模块属性更新相关的问题,这些问题没有传播到Windows上的子进程 以下代码片段说明了该问题: 导入工具 导入多处理 导入操作系统 从contextlib导入contextmanager _域\范围\范围='reference' def get_domain_range_scale(): 返回(域)范围(尺度) def set_domain_range_scale(scale='Reference'): 全局(域)范围(尺度) 刻度=str(刻度)。下() _域\范

我遇到一些与Windows上的模块属性更新相关的问题,这些问题没有传播到Windows上的子进程

以下代码片段说明了该问题:

导入工具
导入多处理
导入操作系统
从contextlib导入contextmanager
_域\范围\范围='reference'
def get_domain_range_scale():
返回(域)范围(尺度)
def set_domain_range_scale(scale='Reference'):
全局(域)范围(尺度)
刻度=str(刻度)。下()
_域\范围\比例=比例
类域\范围\比例(对象):
def ___;初始(自身,比例):
自刻度=刻度
self.\u previous\u scale=get\u domain\u range\u scale()
定义输入(自我):
设置\u域\u范围\u刻度(自刻度)
回归自我
定义退出(自我,*args):
设置域范围刻度(自刻度)
定义调用(自身,功能):
@functools.wrapps(函数)
def包装(*args,**kwargs):
与自我:
返回函数(*args,**kwargs)
返回包装器
@上下文管理器
def多处理池(*args,**kwargs):
池=多处理。池(*args,**kwargs)
收益池
pool.terminate()
def测试域范围刻度(*参数):
打印('Domain Range Scale internal:{0},PID:{1}'。格式(
获取_域_范围_比例(),os.getpid())
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
对于“参考”、“1”、“100”中的比例:
具有域\范围\比例(比例):
打印('*'*79)
打印('Domain Range Scale Outer:{0},PID:{1}'。格式(
获取_域_范围_比例(),os.getpid())
使用多处理池(进程=4)作为池:
地图(测试域范围比例尺,范围(10))
Linux/macOS上的输出

*******************************************************************************
Domain Range Scale Outer: reference, PID: 93989
Domain Range Scale Inner: reference, PID: 93990
Domain Range Scale Inner: reference, PID: 93992
Domain Range Scale Inner: reference, PID: 93993
Domain Range Scale Inner: reference, PID: 93991
Domain Range Scale Inner: reference, PID: 93990
Domain Range Scale Inner: reference, PID: 93991
Domain Range Scale Inner: reference, PID: 93990
Domain Range Scale Inner: reference, PID: 93993
Domain Range Scale Inner: reference, PID: 93991
Domain Range Scale Inner: reference, PID: 93992
*******************************************************************************
Domain Range Scale Outer: 1, PID: 93989
Domain Range Scale Inner: 1, PID: 93994
Domain Range Scale Inner: 1, PID: 93995
Domain Range Scale Inner: 1, PID: 93996
Domain Range Scale Inner: 1, PID: 93997
Domain Range Scale Inner: 1, PID: 93994
Domain Range Scale Inner: 1, PID: 93995
Domain Range Scale Inner: 1, PID: 93996
Domain Range Scale Inner: 1, PID: 93994
Domain Range Scale Inner: 1, PID: 93997
Domain Range Scale Inner: 1, PID: 93995
*******************************************************************************
Domain Range Scale Outer: 100, PID: 93989
Domain Range Scale Inner: 100, PID: 93998
Domain Range Scale Inner: 100, PID: 93999
Domain Range Scale Inner: 100, PID: 94000
Domain Range Scale Inner: 100, PID: 94001
Domain Range Scale Inner: 100, PID: 93998
Domain Range Scale Inner: 100, PID: 93999
Domain Range Scale Inner: 100, PID: 94000
Domain Range Scale Inner: 100, PID: 94001
Domain Range Scale Inner: 100, PID: 93998
Domain Range Scale Inner: 100, PID: 93999
在Windows上输出

*******************************************************************************
Domain Range Scale Outer: reference, PID: 6524
Domain Range Scale Inner: reference, PID: 2124
Domain Range Scale Inner: reference, PID: 2124
Domain Range Scale Inner: reference, PID: 5476
Domain Range Scale Inner: reference, PID: 4872
Domain Range Scale Inner: reference, PID: 1932
*******************************************************************************
Domain Range Scale Outer: 1, PID: 6524
Domain Range Scale Inner: reference, PID: 2716
Domain Range Scale Inner: reference, PID: 2716
Domain Range Scale Inner: reference, PID: 1012
Domain Range Scale Inner: reference, PID: 1852
Domain Range Scale Inner: reference, PID: 6544
*******************************************************************************
Domain Range Scale Outer: 100, PID: 6524
Domain Range Scale Inner: reference, PID: 7456
Domain Range Scale Inner: reference, PID: 7456
Domain Range Scale Inner: reference, PID: 7456
Domain Range Scale Inner: reference, PID: 7456
Domain Range Scale Inner: reference, PID: 5944

您的问题在于Windows不支持“fork”作为新进程的启动方法(仅支持“spawn”)。全局变量不是通过“spawn”继承的。 当您在
\u DOMAIN\u RANGE\u SCALE='reference'
下面放置一个print语句时,您将看到Windows上的子进程将再次运行该脚本 直到导入所需函数时,
如果uuuuu name uuuu=='\uuuuuu main uuu':

在进程启动后,必须使用池的
初始值设定项
-参数来显式注册全局变量

...

def init_global(scale):
    global _DOMAIN_RANGE_SCALE
    _DOMAIN_RANGE_SCALE = scale

if __name__ == '__main__':

...
        with multiprocessing.Pool(processes=4,
                                  initializer=init_global,
                                  initargs=(scale,)) as pool:

            pool.map(test_domain_range_scale, range(10))
...

我发现这个答案提到了windows存在的问题:我假设这里的问题是无分叉支持,我会看看初始化器,它很有希望!