Python和FIFO

650*_*502 6 python linux broken-pipe fifo mkfifo

我试图在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")
Run Code Online (Sandbox Code Playgroud)

这是 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)))
Run Code Online (Sandbox Code Playgroud)

我还使用mkfifo input和创建了两个FIFO mkfifo output.

我不明白为什么当我在一些请求之后运行服务器(带python fifoserver.py input output)和客户端(带python fifoclient.py)来自两个控制台后,客户端崩溃并出现"管道损坏"错误f.flush().请注意,在崩溃之前,我已经看到从几百到几千个正确处理的请求运行正常.

我的代码有什么问题?

caf*_*caf 5

正如其他评论所暗示的那样,你有竞争条件.

我怀疑在失败的情况下,服务器在其中一行后被暂停:

g.write(str(x**2) + "\n")
g.close()
Run Code Online (Sandbox Code Playgroud)

然后,客户端可以读取结果,将其打印到屏幕上,然后循环返回.然后它重新打开f- 成功,因为它仍然在服务器端打开 - 并写入消息.同时,服务器已成功关闭f.接下来,客户端上的刷新执行write()管道上的系统调用,这会触发,SIGPIPE因为它现在在另一侧关闭.

如果我是正确的,你应该能够通过将服务器移动f.close()到上面来修复它g.write(...).