Python子进程并不总是清理

时间:2016-12-01 22:41:49

标签: python multithreading process terminate

我正在使用一小段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的多线程功能。我添加了代码来查找这些实例并手动终止它们,它可以检测到挂起的进程,但它似乎无法终止它们,尽管进程已经返回良好的完成状态。我错过了什么?

再次感谢!

0 个答案:

没有答案