我最近一直在学习如何使用Python多处理模块,并阅读官方文档。在16.6.1.2. Exchanging objects between processes中有一个关于使用管道交换数据的简单示例。
并且,在16.6.2.4. Connection Objects中,有这样的陈述,引用“如果没有任何东西可以接收而另一端被关闭则引发 EOFError ”。
所以,我修改了如下所示的示例。恕我直言,这应该触发 EOFError 异常:没有发送任何内容,发送端已关闭。
修订后的代码:
from multiprocessing import Process, Pipe
def f(conn):
#conn.send([42, None, 'hello'])
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
#print parent_conn.recv() # prints "[42, None, 'hello']"
try:
print parent_conn.recv()
except EOFError:
pass
p.join()
但是,当我在我的Ubuntu 11.04机器Python 2.7.2上尝试修改过的示例时,脚本挂起了。
如果有人能指出我错过了什么,我会非常感激。
答案 0 :(得分:9)
当您使用mp.Process
启动新进程时,子进程将继承父进程的管道。当子进程关闭conn
时,父进程仍然打开child_conn
,因此管道文件描述符的引用计数仍然大于0,因此不会引发EOFError。
要获取EOFError,请在父进程和子进程中关闭管道的末尾:
import multiprocessing as mp
def foo_pipe(conn):
conn.close()
def pipe():
conn = mp.Pipe()
parent_conn, child_conn = conn
proc = mp.Process(target = foo_pipe, args = (child_conn, ))
proc.start()
child_conn.close() # <-- Close the child_conn end in the main process too.
try:
print(parent_conn.recv())
except EOFError as err:
print('Got here')
proc.join()
if __name__=='__main__':
pipe()