我对 python 并行化有一个非常具体的问题,让我们看看我是否可以解释它,我想foo()使用多处理库执行一个函数以进行并行化。# Creation of the n processes, in this case 4, and start itthreads = [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: 52, Number of steps: 53, Number of steps: 54, Number of steps: 5也就是说,所有的过程都走“好路”,并以极少的步骤结束。另一方面,其他时候它会返回这个。1, Number of steps: 65162, Number of steps: 84633, Number of steps: 461144, Number of steps: 56312也就是说,所有的进程都走“坏路”。我还没有执行过一次至少有一个走“好路径”而其余走“坏路径”的执行。如果我按foo()顺序运行多次,超过一半的执行以少于 5000 步结束,但在并发中我没有看到这个比例,所有进程要么快要么慢结束。这怎么可能?很抱歉,如果我无法向您提供有关程序和执行的更准确的详细信息,但它太大太复杂,无法在这里解释。
2 回答
慕妹3242003
TA贡献1824条经验 获得超6个赞
您应该使用collections.OrderedDict
(或其他有序数据结构),而不是set
您的程序是否关心项目顺序(random.sample()
例如)。即使在 Python 3.7 及更高版本中,在撰写本文时,set
s 也被记录为无序集合,因此如果插入或枚举项的顺序对您的程序很重要,则不应使用它们。
使用 时set
,您不应期望以任何特定顺序(即使是伪随机顺序)插入或枚举项目。
慕虎7371278
TA贡献1802条经验 获得超4个赞
我已经找到了解决方案,我将其发布以防有人觉得有帮助
问题是,在内部的某个时刻foo()
,我使用了该my_set.pop()
方法而不是set.remove(random.sample (my_set, 1) [0])
. 第一个my_set.pop()
实际上并不返回随机元素。在Python 3.6中,集合有像列表一样的具体顺序,关键是建立的顺序是随机生成的,因此,要返回(伪)随机元素,该方法总是返回第一个元素my_set.pop()
。问题是,就我而言,所有进程都共享该顺序,因此my_set.pop()
在所有进程中返回相同的第一个元素。
添加回答
举报
0/150
提交
取消