我试图了解在Linux下使用Python的FIFO,我发现了一个奇怪的行为,我不明白。
以下是fifoserver.py
import sys import time def readline(f): s = f.readline() while s == "": time.sleep(0.0001) s = f.readline() return s while True: f = open(sys.argv[1], "r") x = float(readline(f)) g = open(sys.argv[2], "w") g.write(str(x**2) + "\n") g.close() f.close() sys.stdout.write("Processed " + repr(x) + "\n")
这是fifoclient.py
import sys import time def readline(f): s = f.readline() while s == "": time.sleep(0.0001) s = f.readline() return s def req(x): f = open("input", "w") f.write(str(x) + "\n") f.flush() g = open("output", "r") result = float(readline(g)) g.close() f.close() return result for i in range(100000): sys.stdout.write("%i, %s\n" % (i, i*i == req(i)))
我还创build了两个使用mkfifo input
和mkfifo output
FIFO。
我不明白的是,为什么当我运行服务器(与python fifoserver.py input output
)和客户端(与python fifoclient.py
)从两个控制台后,一些请求客户端崩溃与f.flush()
上的“破pipe”错误f.flush()
。 请注意,在崩溃之前,我已经看到从几百到几千个正确处理的请求运行良好。
我的代码中有什么问题?
正如其他意见所暗示的,你有一个竞争条件。
我怀疑在失败的情况下,服务器在下列其中一行之后被暂停:
g.write(str(x**2) + "\n") g.close()
客户端然后能够读取结果,将其打印到屏幕,并循环回去。 然后重新打开f
– 成功,因为它仍然在服务器端打开 – 并写入消息。 同时,服务器设法关闭了f
。 接下来,客户端的刷新在管道上执行一个write()
系统调用,它会触发SIGPIPE
因为它现在已经在另一端关闭了。
如果我是正确的,你应该能够通过将服务器的f.close()
移到g.write(...)
之f.close()
修复它。
我不是一个Unix专家,但我的猜测是,你最终会在两个进程中关闭文件,接下来会发生开放性写入。 由于没有什么可以接受的数据,管道中断。
我不明白你为什么总是打开和关闭管道。
尝试启动首先读取管道的过程,让它打开管道,并等待数据。
然后启动管道写入器,并将所有要发送的数据抽出。 如果超前的话,它将会失速。 当作者关闭管道时,阅读器将获得零字节而不是阻塞,并且应该关闭。 IIRC,Python检测到这个并返回EOF。