我有一个运行多个函数的池,它调用一个修饰函数,该函数应附加到全局列表中。这可以正常工作,直到池关闭,此时由于某种原因,一直在增长的列表再次为空。
这里是一些重现我的问题的代码:
import multiprocessing as mp
import functools
foo = []
def decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
foo.append(1)
print(id(foo), foo)
f(*args, **kwargs)
return wrapper
@decorator
def square(n):
return n * n
pool = mp.Pool()
pool.map(square, [i for i in range(1, 5)])
print(id(foo), foo)
这是我实际正在做的事情的简化版本。我不明白的是为什么列表
foo
在pool.map
之后是空的。它是全局定义的,因此每次调用 square
时,都应该附加一个 1
。在此代码中,第一个 1 确实被附加,但没有其他。这不是我的实际代码库中存在的问题。
确实,正确检查包装函数内部的列表表明 1 已被附加,但外部又是空的。在我的实际代码中我得到了相同的行为。在那里,列表正常增长,但是,一旦我在池关闭后再次访问它,它就会变成空的。
为什么列表 foo 在 pool.map 之后是空的
多重处理创建进程。两个进程不共享内存,每个进程都有他的(副本)内存。
foo
在每个进程中都是私有的。因为启动过程中没有修改,所以是空的。
考虑研究
multiprocessing
模块文档、进程间通信方法、线程与进程的区别、线程通信方法。