python子进程死锁

时间:2016-03-10 09:31:32

标签: python numpy queue multiprocessing

似乎python(python 3)队列将被大数据卡住,请参阅以下示例:

import multiprocessing as mp
import numpy as np

class Tester:
    data = None
    def __init__(self):
        self.data = np.zeros((1000,1000))

    def __str__(self):
        return '%f %s' % (self.num, self.name)

def mod(test, out_queue):
    test.num = np.random.randn()
    out_queue.put(test)

if __name__ == '__main__':
    num = 10
    out_queue = mp.Queue()
    tests = []
    for it in range(num):
        tests.append(Tester())
    workers = [ mp.Process(target=mod, args=(test, out_queue)) for test in tests]
    for work in workers: work.start()
    for work in workers: work.join()
    res_lst = []
    for j in range(len(workers)):
        res_lst.append(out_queue.get())

上述代码会导致我的计算机出现死锁,将1000更改为10可以解决问题。

这里发生了什么?

1 个答案:

答案 0 :(得分:1)

在消耗队列中的所有数据之前加入子进程可能会导致死锁,因为子进程在终止之前将等待从队列中删除所有数据。同时,父母将被阻止等待孩子终止 - 这不会发生,因为父母没有从队列中消费孩子的数据。

解决方案是在父级已从队列中使用所有数据之后加入子进程。这包括尚未入队的数据。所以移动

for work in workers: work.join()

到文件的末尾,它将起作用。

这并不完美,因为您需要确保从队列中删除子项中的所有数据。但幸运的是,你的情况很好,因为每个孩子都有一个Queue.put()。如果有多个大" put",父进程将不会收集第二个和后续" puts"并且会发生死锁情况。

"加入使用队列" 的过程中的多处理programming guidelines中解释了这一点。