Python 是否复制管道连接?
在Python多处理中,我看到一些代码执行以下操作Python 是否复制管道连接?,python,multiprocessing,Python,Multiprocessing,在Python多处理中,我看到一些代码执行以下操作 def worker(parent_conn, child_conn): parent_conn.close() while True: x = child_conn.recv() if x == 'close': child_conn.close() break else: do something #
def worker(parent_conn, child_conn):
parent_conn.close()
while True:
x = child_conn.recv()
if x == 'close':
child_conn.close()
break
else:
do something
# Following as master
parent_conn, child_conn = Pipe()
process = Process(target=worker, args=[parent_conn, child_conn])
process.start()
child_conn.close() # not used
for _ in range(10):
parent_conn.send(something)
parent_conn.recv()
parent_conn.send('close')
process.join()
我的问题是
'close'
,那么即使我在主程序中加入了进程,worker while循环似乎也会无限运行fork()
用于生成一个新进程,该进程从父进程继承所有打开的文件描述符。最好的做法是立即关闭分叉后不需要的所有继承的文件描述符,这就是这里要做的。在没有fork()
(windows)的系统上,这就没有什么意义了,因为在windows中,连接的实现方式不同,但仍然有效
父节点和辅助节点都会关闭它们不使用的连接的一端。由于它们是独立的进程,在父进程中调用child\u conn.close()
对辅助进程中的child\u conn
没有影响,它只关闭连接的一端,另一端仍可使用。因此,工作者可以调用client\u-conn
上的recv()
,使用parent\u-conn.send()
将对象发送到父对象中,反之亦然
您的示例实际上不起作用,因为在连接关闭后,在主进程中有一个对child\u conn.recv()
的调用。这将引发一个异常
process.join()
等待进程完成,这只有在循环结束时才会执行,因此如果您从未发送'close'
消息,woker将无限期阻止child\u conn.recv()
,并且join()
将永远不会返回。这是一个典型的死锁
另一种向工作人员发出退出信号的方式是调用
parent\u conn.close()
,而不是发送关闭消息。这将导致child\u conn.recv()
引发EOF错误,但前提是所有进程(包括工作进程)都已关闭基础文件描述符,这也是通常关闭不需要的文件描述符的原因之一。感谢您的详细回答。只是为了确保我是否正确使用它,例如在Ubuntu中,fork()
会复制管道吗?i、 e.在父进程中,有管道的两端,而在辅助进程中,它有一个两端都被复制的独立版本?顺便说一句,如果上面是正确的,那么在主辅助进程模式中,是否更建议只使用args=child\u conn
而不是args=[parent\u conn,child\u conn]创建辅助进程
由于工作进程并不真正使用复制的父连接
进程在fork()上继承打开的文件描述符
在任何情况下,在pickle/unpickle时作为agment传递的连接对象基本上只告诉进程在创建连接对象时使用哪个文件描述符。因此,如果不传递parent\u连接
,您不知道要关闭哪个描述符,在许多应用程序中,哪个描述符可能不是问题。但是,例如,如果您有多个worker使用相同的连接(这需要锁定),那么如果worker中的描述符仍然打开,则在父级中调用close来通知它们停止将不起作用。