Python和FIFO [英] Python and FIFOs

查看:153
本文介绍了Python和FIFO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在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 inputmkfifo 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆