如何在进程完成时停止python多处理服务器

时间:2012-10-20 17:34:24

标签: python multiprocessing distributed-computing

我正在尝试使用python的多处理模块在几台机器上运行分布式任务,我一直在使用this blog post作为参考。

但是,此帖子的任务使用作业队列,并将结果放入结果队列,这两个队列都由JobQueueManager(子类SyncManager)管理。该管理器有一个服务器,当它调用manager.shutdown()时,它会启动并持续运行,直到结果队列被填满。

我的问题是我的任务不需要结果队列,所以我想弄清楚如何知道何时停止服务器。我可以让服务器连续运行serve_forever,然后手动停止它,或创建一个以与示例相同的方式填充的虚拟队列,并在服务器与原始数字一样大时停止服务器工作。

我宁愿不手动停止它,但第二种解决方案看起来相当hacky。似乎一种常见的方式(没有服务器)是在每个进程上调用join(),但我不知道管理器是否有办法找出哪个进程从队列中删除了每个作业。

我的后备计划是虚拟队列方法的一种变体,但有一个共享计数器变量,它作为每个进程的最后一步递增,但我想知道是否有任何建议使用多处理库中的方法,或者这是不可靠的。

由于

编辑:我没有提到我不使用结果队列的原因是我将处理结果存储到Redis数据库。

2 个答案:

答案 0 :(得分:1)

在给出的例子中:

outdict = shared_result_q.get()

结果队列用于异步等待结果。这是主要的沟通方式。没有它,您需要另一种信号机制来确认任务结束事件。只需将None放在队列中即可。

答案 1 :(得分:0)

正如我的更新所示,我已经使用redis数据库存储我的任务结果,因此我不必担心在不同机器之间管理dict。

我最终使用的解决方案也使用了Redis数据库。每当完成每个流程时,我都会将流程'info'的字符串推送到列表(redis-py中的r_server.lpush(...))。在服务器端,我使用Redis的阻塞弹出get,而不是使用阻塞rs.blpop()方法作为结果队列。

这与博客帖子和其他建议在这里制作虚拟队列和使用get()几乎相同,但只是使用redis所以我没有额外的方法参数的开销和注册额外的方法与经理。