我的 Python 多进程显然不是独立的
Posted
技术标签:
【中文标题】我的 Python 多进程显然不是独立的【英文标题】:my Python multiprocesses are apparently not independent 【发布时间】:2020-12-29 20:38:00 【问题描述】:我对 python 并行化有一个非常具体的问题,让我们看看能否解释一下,
我想使用多处理库执行函数foo()
进行并行化。
# Creation of the n processes, in this case 4, and start it
threads = [multiprocessing.Process(target=foo, args=(i)) for i in range(n)]
for th in threads:
th.start()
foo()
函数是一个递归函数,它深入探索一棵树,直到发生一个特定事件。根据它在树中扩展的方式,此事件可以在几个步骤中发生,例如 5 甚至数百万。树节点是一组元素,在每个步骤中,我使用 rand_element = random.sample(node.set_of_elements,1)[0]
从该集合中选择一个随机元素,并相应地对它们进行递归调用,即两个不同的随机元素具有不同的树路径。
问题在于,由于某些未知原因,这些进程显然不能独立运行。例如,如果我并行运行 4 个进程,有时它们会返回此结果。
1, Number of steps: 5
2, Number of steps: 5
3, Number of steps: 5
4, Number of steps: 5
也就是说,所有的过程都走“好路”,并以极少的步骤结束。另一方面,其他时候它会返回 this。
1, Number of steps: 6516
2, Number of steps: 8463
3, Number of steps: 46114
4, Number of steps: 56312
也就是说,所有的进程都走“坏路”。我还没有一次执行,其中至少有一个走“好路”,其余的走“坏路”。
如果我顺序运行foo()
多次,超过一半的执行以不到5000 步结束,但在并发时我看不到这个比例,所有进程要么快要么慢地结束。
怎么可能?
很抱歉,如果我不能为您提供有关程序和执行的更准确的详细信息,但这里太大太复杂无法解释。
【问题讨论】:
您可能对random
伪随机值有一些问题。我建议打印他们选择的节点,看看是否有某种模式。如果是这种情况,使用当前时间(以微秒为单位)乘以进程数应该为每个进程提供一个唯一的种子。请记住,在这种情况下,只有时间可能相等或可能不相等(这就是我乘以进程数的原因)。
谢谢你的回答,我用多个种子试过了,我刚试过你提到的这个,结果是一样的,所有的过程都走相同的路径。你看到多进程的创建和启动好吗?
我觉得还不错。
【参考方案1】:
我找到了解决办法,我把它贴出来以防有人觉得它有帮助
问题是在foo()
内部的某个时刻,我使用了my_set.pop()
方法而不是set.remove(random.sample (my_set, 1) [0])
。第一个 my_set.pop()
实际上并不返回随机元素。在 Python 3.6 中,集合有一个像列表一样的具体顺序,关键是建立的顺序是随机生成的,因此,要返回一个(伪)随机元素,my_set.pop()
方法总是返回第一个元素。问题是,在我的例子中,所有进程共享该顺序,因此my_set.pop()
在所有进程中返回相同的第一个元素。
【讨论】:
你应该注意我的回答。【参考方案2】:如果您的程序关心项目顺序(例如 random.sample()
所做的那样),您应该使用 collections.OrderedDict
(或其他有序数据结构)而不是 set
。即使在 Python 3.7 中,set
s 也是 documented as unordered collections,因此如果插入或枚举项的顺序对您的程序很重要,则不应使用它们。
使用set
,您不应期望以任何特定顺序插入或枚举项目,即使是以伪随机顺序。
另见:
Does Python have an ordered set? Are dictionaries ordered in Python 3.6+? https://***.com/a/64855489/815724【讨论】:
以上是关于我的 Python 多进程显然不是独立的的主要内容,如果未能解决你的问题,请参考以下文章