Python *为什么多处理序列化我的函数和闭包?
据 多处理分叉为*nix创建一个工作进程来执行任务。我们可以通过在fork之前的模块中设置一个全局变量来验证这一点。 如果辅助函数导入该模块并发现变量存在,则进程内存已被复制。事实如此:Python *为什么多处理序列化我的函数和闭包?,python,multiprocessing,python-multiprocessing,Python,Multiprocessing,Python Multiprocessing,据 多处理分叉为*nix创建一个工作进程来执行任务。我们可以通过在fork之前的模块中设置一个全局变量来验证这一点。 如果辅助函数导入该模块并发现变量存在,则进程内存已被复制。事实如此: import os def f(x): import sys return sys._mypid # <<< value is returned by subprocess! def set_state(): import sys sys._mypid
import os
def f(x):
import sys
return sys._mypid # <<< value is returned by subprocess!
def set_state():
import sys
sys._mypid = os.getpid()
def g():
from multiprocessing import Pool
pool = Pool(4)
try:
for z in pool.imap(f, range(1000)):
print(z)
finally:
pool.close()
pool.join()
if __name__=='__main__':
set_state()
g()
我们得到:
AttributeError: Can't pickle local object 'g.<locals>.f'
Stackoverflow和internet都有很多方法可以解决这个问题。Python的标准pickle函数可以处理函数,但不能处理包含闭包数据的函数
但我们为什么要到这里来?f的一个写时拷贝版本在分叉进程的内存中。为什么它需要序列化?Derp-必须这样,因为:
pool = Pool(4) <<< processes created here
for z in pool.imap(f, range(1000)): <<< reference to function
用法:
def f(x):
time.sleep(0.01)
if x ==-1:
raise Exception("Boo")
return x
for result in parallel_map(target=f, <<< not serialized
args=range(100),
num_processes=8,
start_method="fork"):
pass
。。。注意:当你分叉时,程序中的每一个线程都会有一只小狗死亡。Derp-必须这样,因为:
pool = Pool(4) <<< processes created here
for z in pool.imap(f, range(1000)): <<< reference to function
用法:
def f(x):
time.sleep(0.01)
if x ==-1:
raise Exception("Boo")
return x
for result in parallel_map(target=f, <<< not serialized
args=range(100),
num_processes=8,
start_method="fork"):
pass
。。。有一点需要注意:当你使用叉子时,程序中的每一个线程都会导致一只小狗死亡。没关系,我已经搞定了。这是因为在调用池和分叉进程时f不可用。您可以编写自己的答案question@user48956:请注意,这不是时间问题:构建池时存在f,但它无法知道如何隐藏对它的引用,以避免在imap期间需要传输对它的一些描述。可以想象在fork时提供了一个非全局对象的“care package”,但是因为这对spawn方法没有帮助,所以它可能不是优先级。对于spawn来说是这样的。叉子不是这样的。没关系,我想出来了。这是因为在调用池和分叉进程时f不可用。您可以编写自己的答案question@user48956:请注意,这不是时间问题:构建池时存在f,但它无法知道如何隐藏对它的引用,以避免在imap期间需要传输对它的一些描述。可以想象在fork时提供了一个非全局对象的“care package”,但是因为这对spawn方法没有帮助,所以它可能不是优先级。对于spawn来说是这样的。叉子不是这样的。