我在多进程中遇到了一种奇怪的行为。
当我试图在从多进程调用的函数中使用全局变量时,它看不到全局变量。
示例:
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。然而,当我用多进程调用相同的函数时,它显示变量variable不存在,即使在我之前清楚地打印了它之后也是如此。
多重处理会忽略全局变量吗?我该如何解决这个问题呢?
发布于 2016-08-23 16:05:42
在创建Pool的那一刻,multiprocessing Pool的fork (或者以一种旨在模仿Windows的方式)它的工作进程。forking将父内存映射为子内存中的写入时复制,但它不会在它们之间创建持久的联系;在fork之后,在父内存中所做的更改在子内存中不可见,反之亦然。您不能使用在创建Pool之后定义的任何变量,并且在创建Pool之前对变量所做的更改不会反映在workers中。
通常,对于Pool,您希望完全避免可变的全局状态;将所有需要的数据作为参数(序列化并发送给子进程,因此状态是正确的)传递给函数imap-ing (或其他任何东西),并让函数return任何新数据,而不是更改全局变量,后者会序列化数据并将其发送回父进程,以便在它认为合适的时候使用。
Managerss是一个选项,但通常不是Pools的正确选项;您通常希望只关注创建Pool之前的只读全局变量,或者使用参数并返回新值,而根本不使用全局状态。
发布于 2016-08-23 16:05:30
当您向一个进程发送垃圾邮件时,所有上下文都被复制,您需要使用managers在它们之间交换对象,检查official documentations,用于管理状态检查this。
https://stackoverflow.com/questions/39095530
复制相似问题