多处理。当进程死亡时,挂起的值

时间:2015-03-06 09:43:27

标签: python multiprocessing

我有multiprocessing.Process的子流程和multiprocessing.Queue的队列。

主要流程是使用multiprocessing.Queue.get()来获取一些新数据。我不想在那里超时,我希望它能够阻止。

但是,当子进程因任何原因死亡(由用户通过kill手动杀死,或段错误等)时,Queue.get()将永远挂起。

我该如何避免?

2 个答案:

答案 0 :(得分:4)

我认为multiprocessing.Queue不是我想要的。

我现在正在使用

parent_conn, child_conn = multiprocessing.Pipe(duplex=True)

获取两个multiprocessing.Connection个对象。然后我os.fork()或使用multiprocessing.Process。在孩子身上,我做了:

parent_conn.close()
# read/write on child_conn

在父母(在分叉之后),我做:

child_conn.close()
# read/write on parent_conn

这样,当我在连接上调用recv()时,当子/父在此时死亡时,它将引发异常(EOFError)。

请注意,这仅适用于单个孩子。我想Queue是指你需要多个孩子的时候。在这种情况下,你可能会有一些经理监督所有孩子是否还活着并重新开始。

答案 1 :(得分:1)

Queue无法知道何时没有任何可能的作家。您可以将对象传递给任意数量的子进程,并且它不知道您是否将它传递给任何给定的子进程。所以它必须等待,即使子进程死了。队列是一个文件描述符,当孩子死亡时会自动关闭。

您正在寻找的是父母流程中的某种主管,它会注意到孩子意外死亡并以您认为合适的方式处理这种情况。您可以通过捕获SIGCHLD进程,在线程中检查Process.is_alive或使用Process.join来执行此操作。一个简单的实现将使用timeout调用中的Queue.get参数,并在返回时执行Process.is_alive检查。

如果你对子进程的死亡有了更多的控制权,它应该向队列发送一个“EOF”类型的对象(None,或者它已经完成的某种标记),这样你的父进程可以正确处理它。