多处理看不到全局变量?

Multiprocessing does not see global variables?

我 运行 在多处理时出现奇怪的行为。

当我尝试在从多处理调用的函数中使用全局变量时,它看不到全局变量。

示例:

import multiprocessing

def func(useless_variable):
    print(variable)

useless_list = [1,2,3,4,5,6]
p = multiprocessing.Pool(processes=multiprocessing.cpu_count())
variable = "asd"

func(useless_list)

for x in p.imap_unordered(func, useless_list):
    pass

输出:

asd
multiprocessing.pool.RemoteTraceback: 
"""
Traceback (most recent call last):
  File "/usr/lib/python3.4/multiprocessing/pool.py", line 119, in worker
    result = (True, func(*args, **kwds))
  File "pywork/asd.py", line 4, in func
    print(variable)
NameError: name 'variable' is not defined
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "pywork/asd.py", line 11, in <module>
    for x in p.imap_unordered(func, useless_list):
  File "/usr/lib/python3.4/multiprocessing/pool.py", line 689, in next
    raise value
NameError: name 'variable' is not defined

正如你第一次看到的那样,我只是简单地调用 func 它按预期打印 asd。但是,当我使用 multiprocessing 调用完全相同的函数时,它说变量 variable 不存在,即使我之前清楚地打印了它。

多处理是否忽略全局变量?我该如何解决这个问题?

当您向进程发送垃圾邮件时,所有上下文都会被复制,您需要使用 managers for exachanging objects between them, check the official documentations, for managing state check this

multiprocessing Pools fork(或以模仿 Windows 上的分叉的方式产生)它的工作进程在 Pool 创建的那一刻。 forking 将 parent 内存映射为 children 中的 copy-on-write,但不会在它们之间创建持久联系;在 fork 之后,在 parent 中所做的更改在 children 中不可见,反之亦然。您不能使用在创建 Pool 之后定义的任何变量,并且在创建 Pool 之前对变量所做的更改将不会反映在工作人员中。

通常,对于 Pool,您希望完全避免可变全局状态;将所有需要的数据作为参数传递给你正在 imap-ing(或其他)的函数(这些数据被序列化并发送到 children,因此状态是正确的),并具有函数return 任何新数据而不是改变全局变量,后者将其序列化并将其发送回 parent 进程以在它认为合适的情况下使用。

Managerss 是一个选项,但通常不是 Pools 的正确选项;您通常只想让工作人员只查看 Pool 创建之前的只读全局变量,或者使用参数并返回新值,根本不使用全局状态。