1

状況は次のとおりです。一部のプロセスは、(で作成されたmkfifo)fifoファイルに行を書き込みます。プログラムのある時点で、FIFOの最後の行を読み、他のすべての行を破棄したいと思います。FIFOの行が1行未満の場合にのみ、プロシージャがブロックされることがあります。

私はこれを行うためのきれいな方法を思い付くことができません、何かアイデアはありますか?

編集:書き込みプロセスは、FIFOへの行の書き込みを停止することはありません。最後の行が意味するのは、FIFOを読み取るまでの最後の行です。必ずしもEOFが続くとは限りません。

4

3 に答える 3

2

読み取りがブロックされることが主な懸念事項である場合は、FIFOを非ブロックとして開きます。私はあなたがストリームで探しているものを知っていると思います、そして単に前にすべてを捨てるでしょう。

select()のようなものを使用して、パイプから読み取るものがあるときに通知を受けることもできます。

于 2010-02-21T15:41:13.763 に答える
2

私があなたの問題を正しく理解した場合、あなたはあなたのプログラムにデータを供給する別のプロセスを持っていますfifo、そして新しいデータは以前に受け取ったデータを時代遅れにします、それであなたは利用可能な最新のデータだけに興味があります。

この場合、私のアプローチは次のようになります-syscallのフラグをfifo使用しての記述子に非ブロッキングモードを設定し、次のようなものを使用します。O_NONBLOCKfcntl()

while (!exit_condition) {
    bytes = read(fd, wrkbuf, sizeof(wrkbuf));  // error handling omitted
    if (0 == bytes && bytes_to_process > 0) {
        process(wrkbuf, bytes_to_process);
        bytes_to_process = 0;
    } else
        bytes_to_process = bytes;
}
于 2010-02-21T20:49:05.720 に答える
1

これを行うために私が考えることができる唯一の方法は、プログラム(1つの読み取り)にFIFO内のすべての情報を読み取らせることです。つまり、プログラム内の読み取りポインターは常にパイプの最後にあります。メッセージが読み取られると、そのメッセージをメッセージの内部リスト(つまり、キューなど)に追加します。また、最後に読み取られたメッセージへのポインタを維持します。

したがって、最後の行を読み取り、他のすべての行を破棄することは、最後のメッセージへのポインターをたどり、必要に応じてキューをクリアするプロセスです。

ここでの問題は、内部キューが大きくなる可能性があることと、キューと最後のメッセージポインタの同時実行制御が必要になることです。パイプをリッスンする以外に何もしない独自のスレッドでFIFOリーダーを使用します。メッセージが届いたら、キューをロックし、新しいメッセージを追加して最後のメッセージポインタを更新してから、ロックを解除する必要があります。ロックを解除する前に、使用可能なすべての着信メッセージを処理していることを確認してください。処理を行うスレッドでは、キューをロックして操作する必要があります。絶対に必要な時間以上キューをロックしていないことを確認してください。そうしないと、パフォーマンスの問題が発生します。

于 2010-02-21T15:19:22.910 に答える