我正在使用一小段Python(2.7.3)来运行一个脚本,该脚本不断监视消息/队列代理并处理它找到的条目。由于体积,处理以多处理方式嵌入,看起来有点像这样:
result = Queue()
q = JoinableQueue()
process_pool = []
for i in range(args.max_processes):
q.put(i)
p = Process(target=worker, args=(q, result, broker, ...))
process_pool.append(p)
#Start processes
for p in process_pool:
p.start()
#Block until completion
q.join()
logger.warning("All processes completed")
尽管代码定期迭代并记录所有进程已完成,但我发现PID逐渐堆积在args.max_processes之外。
我在这个结尾添加了一个额外的块:
for p in process_pool:
if p.is_alive():
logger.warning("Process with pid %s is still alive - terminating" % p.pid)
try:
p.terminate()
except exception as e:
logger.warning("PROBLEM KILLING PID: stack: %s" % e)
我收到了清除平板的所有进程,再次启动,我可以清楚地看到记录器非常间歇地显示一个实例,即如果PID已经标记完成到父进程并且终止进程失败,它仍然存在杀了它。
我将记录器输出添加到各个线程,并且每个线程都记录成功,表明它在向父进程发送信号完成之前已经干净地完成,但它仍然存在。
因为我计划随着时间的推移将其作为一项服务运行,所以周围的流浪过程的数量可能会导致问题,因为它们堆叠成数千个。
我喜欢洞察我错过的和做错的事情。
谢谢
编辑:更新 - 为问题完整性添加工作区块概述: 工作者与消息/队列代理进行交互,由于在一些调试日志消息之外,所有内容都包含在try / except块中,并且每个线程似乎都运行完成,即使在某些情况下,我也会省略其中的详细信息。当一个子进程落后时。
def worker(queue, result_queue, broker, other_variables...):
logger.warning("Launched individual thread")
job = queue.get()
try:
message_broker logic
except Exception as e:
result_queue.put("Caught exception: %s" % e.message)
logger.warning("Individual thread completed cleanly...")
queue.task_done()
迭代问题。在没有抛出和捕获任何异常的情况下,我可以看到所有日志记录指示n个线程已启动,运行完成,并在每次迭代时完成良好状态。阻塞" q.join()"在每次完成所有线程完成返回之前无法完成的调用,但是会留下一些非常少量的进程。我可以用ps -ef看到它们,如果我超时监视它们的数量,它会逐渐增加,直到它打破了Pythons的多线程功能。我添加了代码来查找这些实例并手动终止它们,它可以检测到挂起的进程,但它似乎无法终止它们,尽管进程已经返回良好的完成状态。我错过了什么?
再次感谢!