我對 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
提交
取消