2015-02-23 27 views
0

使用這樣是與python中的多處理器需要同步嗎?

def execute_run(list_out): 
    ... do something 

pool = ThreadPoolExecutor(6) 
for i in list1: 
    for j in list2: 
      pool.submit(myfunc, list_out) 
pool.join() 

假設線程修改list_out一個代碼時,它們可以做,在一個同步的方式?

+0

那是來自'concurrent.futures'庫的'ThreadPoolExecutor'嗎?如果是這樣,我不認爲它有一個'加入'方法。你的意思是'關機'? – 2015-02-23 19:07:06

+1

'execute_run'中發生了什麼?結果是否取決於之前的執行? – Jimilian 2015-02-23 19:28:30

+0

我基本上需要一個地方,每個線程可以把結果,可能是一個列表,以沒有競爭條件的方式。 – Bobo 2015-02-24 04:07:15

回答

1

如果你的目標是以多處理方式計算某些東西,最好不要共享狀態。 我建議你用簡單的mapmultiprocessing如果可能的話:

from multiprocessing import Pool 

input_list = [] 
for i in list1: 
    for j in list2: 
     input_list.append((i, j)) 

p = Pool() 
result_list = p.map(do_something, input_list) 

map作品像循環:

def naive_map(input_list, do_something): 
    result = [] 
    for i in input_list: 
    result.append(do_something(i)) 
    return result 

所以,如果你想使用已接受幾個參數的功能,你可以使用lambda函數來解包元組。

>> def your_function(v1, v2): 
    >>  return v1+v2 
    >> f = lambda (x,y): your_function(x, y) 
    >> map(f, [(1,2),(3,4),(5,6)]) 
     [3, 7, 11] 
+0

這樣他們會以同步的方式修改input_list對嗎? – Bobo 2015-02-23 19:51:01

+0

@Bobo,這樣他們就不會**修改input_list。他們只會讀它。所以,如果你能以這種方式準備你的數據進行處理,你應該這樣做。 – Jimilian 2015-02-23 19:54:08

+0

我需要他們能夠在完成後的某個地方寫出結果。我會怎麼做呢? – Bobo 2015-02-24 03:56:54

1

答案是每個進程都會收到列表的副本,所以不會看到其他進程所做的更改。

要達到您想要的效果,您必須使用Manager來創建列表代理。請注意,經理代理類不知道成員何時發生了變異。例如,如果列表代理的某個元素以某種方式發生了變化,那麼列表代理無法知道這一點。您必須重新分配該成員以刷新更改。從文檔的一個例子:

# create a list proxy and append a mutable object (a dictionary) 
lproxy = manager.list() 
lproxy.append({}) 
# now mutate the dictionary 
d = lproxy[0] 
d['a'] = 1 
d['b'] = 2 
# at this point, the changes to d are not yet synced, but by 
# reassigning the dictionary, the proxy is notified of the change 
lproxy[0] = d 
+2

OP正在使用'ThreadPoolExecutor',而不是'ProcessPoolExecutor'。所以每個線程都在修改相同的列表。 – 2015-02-23 19:04:14

+0

你有指向一個例子的指針嗎?我需要做一些事情,比如我上面發佈的代碼,每個線程修改提供的參數列表。謝謝 – Bobo 2015-02-23 19:18:11

+0

我認爲你可以換句話來更清楚一點。我認爲它目前的措辭是這樣的,它給人的印象是,諸如追加到託管列表或從託管列表彈出的變化將不會被傳播。指定缺乏傳播只適用於可變項目是很好的。 – skrrgwasme 2015-02-23 19:35:02

2

multiprocessing線程池只是線程,沒有任何魔法一般同步共享對象。你需要用鎖來保護共享對象。

+0

或更好的是,重構代碼,以便不共享任何對象(除了以只讀方式),而是在主線程中整理輸出對象,之後其他線程已經運行。 – 2015-02-23 19:17:29