Python多处理 - 为什么我的进程没有返回/完成?

时间:2017-03-05 21:26:34

标签: python python-3.x

我试图并行化我的一个长时间运行的任务。出于某种原因,它只是不会完成并永远悬挂。

import multiprocessing as mp

class PartitionedResult(object):
    index = 0
    P = []
    def __init__(self, index, P):
        self.index = index
        self.P = P        


def longRunningTask(index, output):
    P = []
    for i in range (0, 1000):        
        print(i)
        P.append(i)

    print("I'm done!")
    output.put(PartitionedResult(index, P))
    return

def main():
    output = mp.Queue()
    processes = [mp.Process(target=longRunningTask, args=(x,output,)) for x in range(4)]
    for p in processes:
        p.start()

    for p in processes:
        p.join()

    results = [output.get() for p in processes]
    print("This never shows up")



if __name__ == '__main__':
    main()

它为4个过程中的每一个打印数字0-999,它甚至达到了'#34;我完成了!"行,但它不会到达results = [output.get() for p in processes]

如果我缩小for循环的范围,让我们说range(0,50),它会突然发挥作用。

这里的问题是什么?

编辑:我在Windows 10上使用Python 3.4,我在2台不同的计算机上尝试过,删除了pycache。

2 个答案:

答案 0 :(得分:3)

在您join()结果之前,您正在调用所有流程get()。当队列的缓冲区填满时,它可以阻止数据刷新到底层管道。如果您join()进程从您的使用者进程中被阻止,则会出现死锁,因为该进程只能在写完所有数据后退出。

将要加入的号码移至main()的末尾,然后它应该有效:

def main():
    output = mp.Queue()
    processes = [mp.Process(target=longRunningTask, args=(x,output,)) for x in range(4)]

    for p in processes:
        p.start()  

    results = [output.get() for p in processes]
    print("This never shows up")

    for p in processes:
        p.join()

答案 1 :(得分:1)

如果某个进程显示为挂起或死锁,则可以强制将其杀死。在流程对象上调用Terminate()会杀死子流程。基本示例:

import multiprocessing
import time

def slow_worker():
print 'Starting worker'
time.sleep(0.1)
print 'Finished worker'

if __name__ == '__main__':
p = multiprocessing.Process(target=slow_worker)
print 'BEFORE:', p, p.is_alive()

p.start()
print 'DURING:', p, p.is_alive()

p.terminate()
print 'TERMINATED:', p, p.is_alive()