6

我试图在 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)))

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

我不明白的是,为什么当我在一些请求后从两个控制台运行服务器(with python fifoserver.py input output)和客户端(with )时,客户端崩溃并出现“断管”错误。请注意,在崩溃之前,我已经看到数百到数千个正确处理的请求运行良好。python fifoclient.pyf.flush()

我的代码有什么问题?

4

2 回答 2

5

正如其他评论所暗示的那样,您有一个竞争条件。

我怀疑在失败的情况下,服务器在这些行之一之后被挂起:

g.write(str(x**2) + "\n")
g.close()

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

如果我是正确的,您应该能够通过将服务器移动f.close()g.write(...).

于 2011-02-23T05:24:16.230 回答
0

我不是 unix 专家,但我的猜测是你最终会在两个进程中关闭文件,然后是 open-for-write。由于没有任何东西可以接受数据,因此管道破裂。

我不明白你为什么一直在打开和关闭管道。

尝试首先启动读取管道的进程,让它打开管道,它会等待数据。

然后启动 pipe-writer,让它抽出你想要发送的所有数据。如果它领先就会停顿。当作者关闭管道时,阅读器获得零字节而不是阻塞,并且应该关闭。IIRC,Python 检测到这一点并返回 EOF。

于 2011-02-22T22:31:12.770 回答