Python多进程从队列中获取结果

时间:2015-05-19 08:38:05

标签: python-2.7 queue multiprocessing

我正在运行一个多处理脚本,该脚本应该启动大约0.01秒的2.000.000个作业。每个作业都将结果放入从队列导入的队列中,因为多处理模块中的队列无法处理超过517个结果。

我的程序在从队列中获取结果之前冻结。这是我的多进程函数的核心:

while argslist != []:
    p = mp.Process(target=function, args=(result_queue, argslist.pop(),))
    jobs.append(p)
    p.start()
for p in jobs:
    p.join()
print 'over'

res = [result_queue.get() for p in jobs]
print 'got it'

输出:" over"但从来没有"得到它"

当我替换

result_queue.get() 

通过

result_queue.get_nowait()

我得到了提升空错误,说我的队列是空的......

但是如果我在我的内部函数中的queue.put()之后执行queue.get(),那么它可以工作,向我显示我的函数已经很好地归档了队列..

2 个答案:

答案 0 :(得分:1)

queue.Queue不在流程之间共享,因此无法使用,您必须使用multiprocessing.Queue

为避免死锁,您不应在从队列中获取结果之前加入您的进程。 multiprocessing.Queue实际上受其底层管道缓冲区的限制,因此如果填满,则不会有更多项目被刷新到管道,queue.put()将阻塞,直到消费者调用queue.get(),但是消费者正在加入一个被阻止的进程,然后你就陷入了僵局。

您可以使用multiprocessing.Pool及其map()来避免所有这些。

答案 1 :(得分:0)

谢谢mata,我切换回multiprocessing.Queue()但我不想使用池,因为我想跟踪运行的作业数量。我最后添加了一个if语句来定期清空我的队列。

def multiprocess(function, argslist, ncpu):
    total = len(argslist)
    done = 0
    result_queue = mp.Queue(0)
    jobs = []
    res = []
    while argslist != []:
        if len(mp.active_children()) < ncpu:
            p = mp.Process(target=function, args=(result_queue, argslist.pop(),))
            jobs.append(p)
            p.start()
            done += 1
            print "\r",float(done)/total*100,"%", #here is to keep track
        # here comes my emptying step
        if len(jobs) == 500:
            tmp = [result_queue.get() for p in jobs]
            for r in tmp:
                res.append(r)
            result_queue = mp.Queue(0)
            jobs = []

    tmp = [result_queue.get() for p in jobs]
    for r in tmp:
        res.append(r)
    return res

然后我想起了这个问题:
因为python或我的机器或我的系统,500个工作是限制吗? 如果我的多处理功能在其他条件下使用,这个阈值是否会出错?