我正在运行一个多处理脚本,该脚本应该启动大约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(),那么它可以工作,向我显示我的函数已经很好地归档了队列..
答案 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个工作是限制吗?
如果我的多处理功能在其他条件下使用,这个阈值是否会出错?