2013-07-07 47 views
1

我从来没有使用过多处理模块。python:理解多处理的简单for循环

有没有一种方法可以将一个循环做成并发子进程。像

for i in xrange(10): list.append(i) 

而不是顺序,使其平行?

我尝试使用队列模块

q = Queue.Queue() 

for i in xrange(10): 
    q.put(i) 


def addto(q): 
    new.append(q.get(block=False)) 


processes = [Process(target=addto, args=(q,))] 
for p in processes: 
    p.start() 
for p in processes: 
    p.join() 

它给出了一个很长的错误,即时通讯粘贴它的最后:

C:\WinPython-64bit-2.7.3.3\python-2.7.3.amd64\lib\pickle.pyc in save_global(self, obj, name, pack) 
    746    raise PicklingError(
    747     "Can't pickle %r: it's not found as %s.%s" % 
--> 748     (obj, module, name)) 
    749   else: 
    750    if klass is not obj: 

PicklingError: Can't pickle <type 'thread.lock'>: it's not found as thread.lock 

我也看到这个很多:

processes = [Process(target=func, args=(q,x)) for i in some iterable] 

所以好吧有一个func(q,x)好吧,我有一个map()或者for循环/而进入我的函数func(),那么为什么迭代过程,再一次? 我不想循环使用过程的整个功能,但只是使这些特定的循环并行进程。为什么用args迭代目标函数?我的意思是当我已经q.put它?

如果我做

processes = Process(target=addto, args=(q,)).start() 
+0

“我的意思是我什么时候已经q.put?”究竟!你的例子太微不足道了。即使没有'q.put()'循环,也没有足够的工作来证明它在进程之间分配。 –

+0

@BrianCain我知道这很愚蠢,但我可以用线程来理解它们是如何工作的。我想知道过程如何工作。特别是对我来说问题是使循环平行。 – user2290820

回答

4

Queue.Queue是线程安全的队列和线程原语不能转移到其他进程。您需要改为multiprocessing.Queue;简单地替换

import Queue 
q = Queue.Queue() 

import multiprocessing 
q = multiprocessing.Queue() 

此外,new必须multiprocessing.managers.list类型。

但是,请注意,您只是复制了multiprocessing.Pool;你可以写

import multiprocessing 

new = multiprocessing.Manager().list() 
def addto(val): 
    new.append(val) 

pool = multiprocessing.Pool() 
for i in xrange(10): 
    pool.apply_async(addto, (i,)) 
pool.close() 
pool.join() 
print(new) 
+0

伟大的洞察力。我没有从多重处理进口队列。可以,不适当更新与那 – user2290820

+0

新发生的事情仍然是空的new = [] – user2290820

+0

@ user2290820更新了一个完整的例子,这对我来说很好(默认情况下,它使用一个进程每个虚拟CPU,因此对于多处理器机器,根据调度情况你甚至会看到不同的结果)。这个例子是否适合你?如果不是,你会得到什么错误信息和输出? – phihag