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一個代碼時,它們可以做,在一個同步的方式?
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一個代碼時,它們可以做,在一個同步的方式?
如果你的目標是以多處理方式計算某些東西,最好不要共享狀態。 我建議你用簡單的map
從multiprocessing如果可能的話:
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]
答案是每個進程都會收到列表的副本,所以不會看到其他進程所做的更改。
要達到您想要的效果,您必須使用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
OP正在使用'ThreadPoolExecutor',而不是'ProcessPoolExecutor'。所以每個線程都在修改相同的列表。 – 2015-02-23 19:04:14
你有指向一個例子的指針嗎?我需要做一些事情,比如我上面發佈的代碼,每個線程修改提供的參數列表。謝謝 – Bobo 2015-02-23 19:18:11
我認爲你可以換句話來更清楚一點。我認爲它目前的措辭是這樣的,它給人的印象是,諸如追加到託管列表或從託管列表彈出的變化將不會被傳播。指定缺乏傳播只適用於可變項目是很好的。 – skrrgwasme 2015-02-23 19:35:02
multiprocessing
線程池只是線程,沒有任何魔法一般同步共享對象。你需要用鎖來保護共享對象。
或更好的是,重構代碼,以便不共享任何對象(除了以只讀方式),而是在主線程中整理輸出對象,之後其他線程已經運行。 – 2015-02-23 19:17:29
那是來自'concurrent.futures'庫的'ThreadPoolExecutor'嗎?如果是這樣,我不認爲它有一個'加入'方法。你的意思是'關機'? – 2015-02-23 19:07:06
'execute_run'中發生了什麼?結果是否取決於之前的執行? – Jimilian 2015-02-23 19:28:30
我基本上需要一個地方,每個線程可以把結果,可能是一個列表,以沒有競爭條件的方式。 – Bobo 2015-02-24 04:07:15