我一直在研究一个大型的Python科学项目,我遇到了堆栈溢出问题,基本上涉及random.sample()
和multiprocessing
。我有一个Goo
对象,其中包含大量Foo
人,他们寻求交朋友。为此,他们使用p
随机选择属于Foo
的{{1}}其他Goo
random.sample()
。一旦完成,程序就会停止。
就是这样:
foo.py
class Foo(object):
def __init__(self):
self.friends = []
goo.py:
from foo import Foo
import random
class Goo(object):
def __init__(self, nfoo):
self.foo_list = [Foo() for i in range(nfoo)]
def sim_goo(self):
for f in self.foo_list:
candidates = random.sample(self.foo_list, 5)
f.friends = candidates
和main.py:
from goo import Goo
def do_sim(argument):
g = Goo(argument)
g.sim_goo()
return g
并使用Jupyter我运行:
from main import do_sim
from multiprocessing import Pool
pool = Pool(processes = 2)
para_list = [1000, 1000]
result = pool.map_async(sim_goo, para_list).get()
引发MaybeEncodingError: Error sending result: '[<goo.Goo object at 0x0000003B15E60A90>]'. Reason: 'RecursionError('maximum recursion depth exceeded while pickling an object',)'
当它与para_list = [10, 10]
一起使用时,我只能想象错误被引发,因为random.sample()变得太大而无法处理它所选择的列表太大,这在使用多处理时会出现问题。但1000 Foos并不多。
有人知道另一种选择吗?
谢谢你的时间!
最佳,
答案 0 :(得分:2)
为了让您的Goo
对象被腌制(将其传输到另一个进程),必须先对其所有Foo
进行腌制。为了挑选每个Foo
,他们的所有朋友Foo
必须先被腌制。并腌制那些 Foo
......等等。很可能会有一连串的友谊链贯穿所有1000 Foo
s(因此在酸洗过程中需要堆栈深度超过1000) - 但是默认的递归限制(在我的Python副本上) ,至少)只有1000。
如果您可以使用1000 Foo
作为限制,则可能会略微提高递归限制 - sys.setrecursionlimit(1050)
。如果您需要更多,则需要采用不同的方法。我想到的第一件事就是将每个Foo
的友谊作为索引列表存储到Goo
的{{1}}中,而不是实际引用其他foo_list
}第