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