[英]Processes fail to exit() when job count exceeds n
我Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
运行Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
。
我产生了4个进程,给它们2个队列-用于任务和结果,最后加入任务队列。 并且当任务计数达到一定数量时(例如njobs = 10000
,即使所有任务都已完成,某些子级和主进程也不会退出。
为什么是这样?
代码来说明这一点
def worker(job_queue, result_queue):
import Queue
while True:
try:
j = job_queue.get(False)
except Queue.Empty:
exit('done')
else:
result_queue.put_nowait(j)
job_queue.task_done()
if __name__ == "__main__":
from multiprocessing import JoinableQueue, Process, cpu_count
job_queue = JoinableQueue()
result_queue = JoinableQueue()
njobs = 10000
for i in xrange(njobs):
job_queue.put(i)
cpus = cpu_count()
for i in xrange(cpus):
p = Process(target=worker, args=(job_queue, result_queue))
p.start()
job_queue.join()
print("DONE")
任务时间越长,挂起某人(或所有)进程所需的任务数量越少。 最初,我正在与此进行序列匹配。 当队列大约为500时,通常会使3个进程挂起。
显然,队列中有6570个以上的项目可能会导致死锁(此线程中的更多信息)。 您可以做的是在主执行结束时输入空result_queue
:
while not result_queue.empty():
result_queue.get(False)
result_queue.task_done()
print "Done"
请注意,您不必在worker函数中调用exit
, return
就足够了:
except Queue.Empty:
print "done"
return
您也可以考虑使用Pool :
from multiprocessing import Pool
def task(arg):
"""Called by the workers"""
return arg
def callback(arg):
"""Called by the main process"""
pass
if __name__ == "__main__":
pool = Pool()
njobs = 10000
print "Enqueuing tasks"
for i in xrange(njobs):
pool.apply_async(task, (i,), callback=callback)
print "Closing the pool"
pool.close()
print "Joining the pool"
pool.join()
print "Done"
这是对管道或套接字的实现限制,已在问题8426中进行了很好的描述:multiprocessing.Queue无法获取()非常大的对象 。 注意它也适用于很多小物体。
解
要么
Queue.cancel_join_thread()
文献资料
请记住,将项目放入队列的进程将在终止之前等待,直到所有缓冲的项目由“ feeder”线程馈送到基础管道为止。 (子进程可以调用队列的cancel_join_thread()方法来避免这种行为。)
这意味着,无论何时使用队列,都需要确保在加入该流程之前,将最终删除队列中已放置的所有项目。 否则,您无法确定将项目放入队列的进程将终止。 还请记住,非守护进程将自动加入。
— 多处理-编程指南
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.