多处理看不到全局变量?
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
Pool
s fork(或以模仿 Windows 上的分叉的方式产生)它的工作进程在 Pool
创建的那一刻。 fork
ing 将 parent 内存映射为 children 中的 copy-on-write,但不会在它们之间创建持久联系;在 fork
之后,在 parent 中所做的更改在 children 中不可见,反之亦然。您不能使用在创建 Pool
之后定义的任何变量,并且在创建 Pool
之前对变量所做的更改将不会反映在工作人员中。
通常,对于 Pool
,您希望完全避免可变全局状态;将所有需要的数据作为参数传递给你正在 imap
-ing(或其他)的函数(这些数据被序列化并发送到 children,因此状态是正确的),并具有函数return
任何新数据而不是改变全局变量,后者将其序列化并将其发送回 parent 进程以在它认为合适的情况下使用。
Managers
s 是一个选项,但通常不是 Pool
s 的正确选项;您通常只想让工作人员只查看 Pool
创建之前的只读全局变量,或者使用参数并返回新值,根本不使用全局状态。
我 运行 在多处理时出现奇怪的行为。
当我尝试在从多处理调用的函数中使用全局变量时,它看不到全局变量。
示例:
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
Pool
s fork(或以模仿 Windows 上的分叉的方式产生)它的工作进程在 Pool
创建的那一刻。 fork
ing 将 parent 内存映射为 children 中的 copy-on-write,但不会在它们之间创建持久联系;在 fork
之后,在 parent 中所做的更改在 children 中不可见,反之亦然。您不能使用在创建 Pool
之后定义的任何变量,并且在创建 Pool
之前对变量所做的更改将不会反映在工作人员中。
通常,对于 Pool
,您希望完全避免可变全局状态;将所有需要的数据作为参数传递给你正在 imap
-ing(或其他)的函数(这些数据被序列化并发送到 children,因此状态是正确的),并具有函数return
任何新数据而不是改变全局变量,后者将其序列化并将其发送回 parent 进程以在它认为合适的情况下使用。
Managers
s 是一个选项,但通常不是 Pool
s 的正确选项;您通常只想让工作人员只查看 Pool
创建之前的只读全局变量,或者使用参数并返回新值,根本不使用全局状态。