Python和FIFO [英] Python and FIFOs
问题描述
我试图在Linux下使用Python理解FIFO,但发现了一个我不理解的奇怪行为.
I was trying to understand FIFOs using Python under linux and I found a strange behavior i don't understand.
以下是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)))
我还使用mkfifo input
和mkfifo output
创建了两个FIFO.
I also created two FIFOs using mkfifo input
and mkfifo output
.
我不明白的原因是为什么当我在某些请求后从两个控制台运行服务器(使用python fifoserver.py input output
)和客户端(使用python fifoclient.py
)时,客户端崩溃并在
What I don't understand is why when I run the server (with python fifoserver.py input output
) and the client (with python fifoclient.py
) from two consoles after some requests the client crashes with a "broken pipe" error on f.flush()
. Note that before crashing I've seen from a few hundreds to several thousands correctly processed requests running fine.
我的代码有什么问题?
推荐答案
正如其他评论所暗示的,您有比赛条件.
As other comments have alluded to, you have a race condition.
我怀疑在失败的情况下,服务器在以下几行之一后被挂起:
I suspect that in the failing case, the server gets suspended after one of these lines:
g.write(str(x**2) + "\n")
g.close()
然后,客户端可以读取结果,将其打印到屏幕上,然后循环播放.然后,它重新打开f
-成功,因为它仍在服务器端打开-并写入消息.同时,服务器已设法关闭f
.接下来,客户端的刷新在管道上执行write()
syscall,这会触发SIGPIPE
,因为它在另一侧已关闭.
The client is then able to read the result, print it to the screen, and loop back. It then reopens f
- which succeeds, because it's still open on the server side - and writes the message. Meanwhile, the server has managed to close f
. Next, the flush on the client side executes a write()
syscall on the pipe, which triggers the SIGPIPE
because it's now closed on the other side.
如果我是正确的话,您应该可以通过将服务器的f.close()
移到g.write(...)
之上来进行修复.
If I'm correct, you should be able to fix it by moving the server's f.close()
to be above the g.write(...)
.
这篇关于Python和FIFO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!