python-即使子进程已关闭,MultiProcessing Pipe recv也会阻塞

阅读有关此主题的几个问题后,我现在知道子进程从父进程继承了文件描述符.当父母关闭连接时,这会使孩子更难收到EOFError.

但是我的情况恰恰相反,我不明白我面临的问题.

我有一个父进程,该进程启动一个子进程,并使其能够访问我创建的Pipe连接的一端.现在,当子进程完成,出现故障或其他任何情况时,所有操作都将停止并关闭连接.此时,子进程显示为已失效.

然后,我希望父进程的连接在阻塞的recv调用上抛出EOFError.但是相反,它只是坐在那里等待.

我在这里想念什么?

编辑

我认为这个例子代表了问题:

from multiprocessing import Process, Pipe
from threading import Thread
import time

class Parent(object):

    def __init__(self):
        self.parent_conn, child_conn = Pipe()
        self.child = Process(target=Child, args=(child_conn,))
        self.child.start()        

        def recv():
            try:
                self.parent_conn.recv()
            except EOFError:
                print "EOF"
            except:
                print "something else"

        # Does not work
        recv()

        # Works fine
        t = Thread(target=recv)
        t.setDaemon(True)
        t.start()

    def close(self):
        self.parent_conn.close()
        self.child.join()

class Child(object):

    def __init__(self, conn):
        conn.close()

if __name__ == "__main__":
    p = Parent()
    time.sleep(1)
    p.close()

如果我确实使用单独的线程,则允许父级关闭其自己的连接,并且一切正常. (请注意,您仍然需要知道子进程的完成方式,才能做到这一点.)相反,如果我直接调用recv,它将明显阻塞,但是我怀疑一旦子进程关闭其连接,它将引发EOFError.但事实并非如此.谁能澄清?

解决方法:

在self.child.start()之后添加child_conn.close().它是idiomatic for working with pipes to close unused ends.(可选)还提供duplex = False参数.

The things is, I don’t know beforehand whether it is going to close right away.. Normally the child should be able to send and receive. Furthermore I still do not get why this won’t work, as is.

>父级中的child_conn.close()并不意味着子级应立即关闭其结尾
> parent_conn.recv直到有机会有人child_conn.send()才会返回.如果child_conn(在孩子或父母中)打开,则有机会

If I do use the separate thread, the parent is allowed to close its own connection and everything works fine. Note that you still need to know somehow that the child is done for, to do this

您不需要知道它.您可以在子级中打开连接后立即关闭.不管孩子做什么,在self.child.start()之后在父级中调用child_conn.close()都很好.

Could you explain the duplex option a little bit more also?

duplex=False表示管道是单向的,即,您只能调用parent_conn.recv()和child_conn.send().否则,它是双向的,并且两个连接都支持send / recv.

上一篇:ubuntu常用


下一篇:LeetCode 589 N-ary Tree Preorder Traversal 解题报告