Python multiprocessing pipe recv() 文档不清晰还是我漏掉了什么?
最近我在学习如何使用Python的多进程模块,并且在阅读官方文档。在16.6.1.2. 进程间交换对象部分,有一个简单的例子,讲的是如何用管道来交换数据。
而在16.6.2.4. 连接对象中,有一句话提到:“如果没有可以接收的内容,并且另一端已经关闭,就会引发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运行这个修改后的例子时,脚本却卡住了。
如果有人能告诉我我遗漏了什么,我会非常感激。
1 个回答
10
当你用 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()