壊れたパイプ!名前付きパイプを使用して2つの独立したプログラムを一緒に接続する問題

壊れたパイプ!名前付きパイプを使用して2つの独立したプログラムを一緒に接続する問題

私は通常、Linuxシステムで直列に実行する2つのコマンドラインプログラムを持っています。

これら2つのプログラムの一般的な実行は次のとおりです。

  1. プログラムAが実行される。単純なテキストファイルをインポートし、単純なテキストファイルを出力します。
  2. プログラムBはAの後に実行され、その入力はプログラムAによって生成されたテキストファイルです。また、単純なテキストファイルを出力します。

注:上記の2つのプログラムの場合、入力と出力は単に対応する入力と出力ファイルのパスです。例: $prog_a /path/to/inputfile/dataIn.txt /path/to/outputfile/dataOut.txt $ prog_b /path/to/inputfile/dataOut.txt /path/to/outputfile/results.txt

これはサードパーティが開発したプログラムです。したがって、私たちはそれらを簡単に修正することはできません(少なくとも時間が経つにつれて)。しかし、名前付きパイプを使用して並列に実行して実行速度を上げたいと思います。データファイルは時々非常に大きく、並列処理が作業速度を上げると考えました。私はこのプロジェクトの課題を受け入れ、次のように進めました。

次のようなbashスクリプトを作成しました。

  1. 両方のプログラムを接続する名前付きパイプを作成します。名前をdataOut.pipeとして指定してください。
  2. プログラムAは通常どおりテキストファイルを読み込みますが、以前のようにテキストファイルに書き込むのではなく、手順1で作成したパイプdataOut.pipeに書き込みます。
  3. プログラムBはパイプを介してプログラムAの出力を読み出す。

Bashスクリプトは次のとおりです。

\#!/bin/bash
mkfifo dataOut.pipe
prog_b dataOut.pipe  results.txt &
prog_a dataIn.txt  dataOut.pipe
rm dataOut.pipe

これはうまくいきます...時々... stderrorでJava例外が発生することがよくあります。問題が正確に何であるかはわかりませんが、次のようになります。

プログラムBが時々Aより速く実行され、Aがデータを入れることができるよりもパイプをより速く消去して全体がクラッシュする可能性がありますか?

この場合、簡単な解決策はありますか?それとも別のことが起こっていますか?

ベストアンサー1

壊れたパイプは、作成者(prog_a)が破損したパイプに書き込もうとしていることを意味します。閉鎖読者(prog_b)によって。 prog_bがなぜそれほど速く停止したのかを知るのに十分な情報を提供していません。

つまり、prog_bは、EOFが満たされるまで、入力ファイルを順次読み込み、通常のUnixフィルタコマンドと同様に、各行を読み取るときに処理すると仮定します。確かですか? prog_bが入力ファイルを検索またはmmapしようとすると失敗する可能性があります(prog_aも同様です)。 prog_bがすべての入力ラインを読み取ってそれを処理したい場合、prog_aとprog_bを並列化するとほとんど何も得られません。なぜなら、prog_bはパイプラインが閉じられたとき(つまり、prog_aが終わったとき)にのみ処理を開始するからです。

おすすめ記事