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また、とを使用して2つのFIFOを作成しましmkfifo outputた。

私が理解していないのは、いくつかのリクエストの後に2つのコンソールからサーバー(with python fifoserver.py input output)とクライアント(with )を実行すると、クライアントpython fifoclient.pyが「壊れたパイプ」エラーでクラッシュする理由f.flush()です。クラッシュする前に、数百から数千の正しく処理されたリクエストが正常に実行されていることを確認したことに注意してください。

私のコードの問題は何ですか?

4

2 に答える 2

5

他のコメントがほのめかしているように、競合状態があります。

失敗した場合、サーバーは次のいずれかの行の後で一時停止されると思われます。

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

その後、クライアントは結果を読み取り、画面に印刷して、ループバックすることができます。次に、再度f開きます(サーバー側でまだ開いているため、成功します)。メッセージを書き込みます。その間、サーバーはなんとか閉じfました。次に、クライアント側のフラッシュがwrite()パイプでsyscallを実行します。これによりSIGPIPE、反対側で閉じられているため、がトリガーされます。

私が正しければ、サーバーf.close()を上に移動することで修正できるはずですg.write(...)

于 2011-02-23T05:24:16.230 に答える
0

私はUNIXの専門家ではありませんが、最終的には両方のプロセスでファイルが閉じられ、次に書き込み用のオープンが発生すると思います。データを受け入れるものがないため、パイプが壊れます。

なぜいつもパイプを開閉しているのかわかりません。

最初にパイプを読み取るプロセスを開始してみてください。パイプを開いてもらうと、データを待機します。

次に、パイプライターを起動し、送信するすべてのデータを出力します。先に進むと失速します。ライターがパイプを閉じると、リーダーはブロックする代わりにゼロバイトを取得し、閉じる必要があります。IIRC、Pythonはこれを検出し、EOFを返します。

于 2011-02-22T22:31:12.770 に答える