2012-11-30 39 views
5

我在我的项目中使用多处理。我有一个将结果放入队列的工作函数。一切正常。但随着x的大小增加(在我的情况下,x是一个数组)出了问题。这里是我的代码的简化版本:Python中的多处理被阻止

def do_work(queue, x): 
    result = heavy_computation_function(x) 
    queue.put(result) # PROBLEM HERE 

def parallel_something(): 
    queue = Queue() 
    procs = [Process(target=do_work, args=i) for i in xrange(20)] 
    for p in procs: p.start() 
    for p in procs: p.join() 

    results = [] 
    while not queue.empty(): 
     results.append(queue.get) 

    return results 

我在系统中看到监控蟒蛇流程工作,但随后事情发生,所有进程都在运行,但什么都不做。这是我输入ctrl-D时得到的结果。

pid, sts = os.waitpid(self.pid, flag) 
KeyboardInterrupt 

我做了一些测试。如果我不把结果放在一切正常的地方,那么这个问题看起来好像是把结果放在队列中,但那样就没有用处。

+4

您似乎从不将队列对象传递给新进程。 'Process'的'args'应该是'tuple'。尝试将其更改为'args =(queue,i)'。你的'queue.get'也需要一些括号,以便它成为'queue.get()'。 – Wessie

回答

3

好吧,它看起来像是在Python的队列模块中的一些错误。事实上使用..

from multiprocessing import Manager 

queue = Manager().Queue() 

..everything的作品,但我仍然不知道为什么.. :)

+0

区别在于你正在实例化'Manager()。Queue()'而不是简单的'Queue()'。我认为这意味着'Manager .__ init __()'在第一个表单中被调用,但不在第二个表单中。 – Patrick

5

你最有可能产生死锁。

programming guidelines

这意味着,无论你使用一个队列,你需要确保在加入过程之前已放入队列中的所有项目最终将被删除。否则,您无法确定将项目放入队列的进程将终止。还要记住,非守护进程会自动加入。

页面中还提出了一种可能的修复方法。请记住,如果流程没有加入,这并不意味着它们在任何意义上“占领”资源。这意味着您可以在流程完成其操作后(可能使用locks)并在稍后加入流程时将排队的数据取出。