主要讲close问题,和recv卡住问题
recv卡住是因为他要等待管道中有数据接收,如果没数据就卡住,但是我想触发EOFError,看被人解释是当管道中数据没有东西时就会抛出EOFError,但是我这里死活不抛出,就是卡住。
后来发现是close的问题,但是下面的代码我也加了close了,
from multiprocessing import Process
from multiprocessing import Pipe
import os
import time
def send(a):
print("这是send子进程的id", os.getpid())
a.send("hello")
a.close()
def recv(b):
print("这是recv子进程的id", os.getpid())
try:
print(b.recv())
print(b.recv())
except EOFError:
print("end")
if __name__ == "__main__":
print("父进程的pid", os.getpid())
a, b = Pipe(True)
p_send = Process(target=send, args=(a,))
p_send.start()
p_recv = Process(target=recv, args=(b,))
p_recv.start()
p_send.join()
p_recv.join()
print("结束了")
假设有一个管道 分为A,B端,A端send数据,B端recv数据(其实是双工,只是这样不乱)
最后想明白了,B端recv报错是在确定了管道的另一端不会有数据传来后才报错,否则就一直阻塞,直到有数据从管道另一端传来。一个进程的A端close了只是这个进程的A端不能send数据了,但是别的进程如果有A端,别的进程就能发送数据,只有当所有进程中的A端都关闭了才能算真正的close了。
、
进程1调用了close,但是进程2仍然能send,进程3也能send,所以管道左边还是能有数据进入,
上边错误代码中,父进程中创建了一个a,b=Pipe(),这里a虽然传入进程中了,但是相当于在父进程里还有一个a端,所以要想上述代码成功运行,那么就要在父进程中使用a.close()才行,但是要注意不能再start函数前close不然会报OSError: handle is closed
如下:
from multiprocessing import Process
from multiprocessing import Pipe
import os
import time
def send(a):
print("这是send子进程的id", os.getpid())
a.send("hello")
a.close()
def recv(b):
print("这是recv子进程的id", os.getpid())
try:
print(b.recv())
print(b.recv())
except EOFError:
print("end")
if __name__ == "__main__":
print("父进程的pid", os.getpid())
a, b = Pipe(True)
p_send = Process(target=send, args=(a,))
p_send.start()
p_recv = Process(target=recv, args=(b,))
p_recv.start()
a.close()
p_send.join()
p_recv.join()
print("结束了")