2015-02-23 77 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