2

コードを変更せずに、外部プログラムから stdin に書き込み、stdout (および stderr ) から読み取ろうとしています。

名前付きパイプを使用してみましたが、プログラムが終了するまで stdout は表示されず、stdin は最初の入力でのみ機能します (次に cin は null です)。

/proc/[pid]/fd を使用してみましたが、プログラムではなく端末からの書き込みと読み取りのみです。

私はこれのためにキャラクターデバイスファイルを書き込もうとしましたが、うまくいきましたが、一度に1つのプログラムしかできませんでした(これは一度に複数のプログラムで動作する必要があります)。

この時点で、私の知る限り、複数のプログラムで io を多重化するように機能するドライバーを作成できましたが、それが「正しい」解決策だとは思いません。

これの主な目的は、Web インターフェイスを介してプログラムのフィードを表示することです。これを行うには何らかの方法が必要だと確信しています。以前に行われたことで、まだ試していないことはありますか?

4

1 に答える 1

5

これを行う典型的な方法は次のとおりです。

  1. pipe(2)新しいプロセスの標準ストリームのシステム コールを使用して匿名パイプ (名前付きパイプではない) を作成します。
  2. fork(2)子プロセスを生成するための呼び出し
  3. close(2)親と子の両方のパイプの適切な端 (たとえば、stdin パイプの場合、親の読み取り端を閉じ、子の書き込み端を閉じます。stdout パイプと stderr パイプの場合は逆)
  4. 子で使用dup2(2)して、パイプ ファイル記述子をファイル記述子 0、1、および 2 にコピーし、次にclose(2)残りの古い記述子をコピーします。
  5. exec(3)子プロセスの外部アプリケーション
  6. 親プロセスでは、同時に子の stdin パイプへの書き込みと、子の stdout および stderr パイプからの読み取りを行います。ただし、子供の振る舞いによっては、注意しないと簡単にデッドロックが発生する可能性があります。デッドロックを回避する 1 つの方法は、3 つのストリームのそれぞれを処理する個別のスレッドを生成することです。もう 1 つの方法は、select(2)システム コールを使用して、ストリームの 1 つがブロックせずに読み書きできるようになるまで待機してから、そのストリームを処理することです。

これをすべて正しく行ったとしても、プログラムの出力がすぐには表示されない場合があります。これは通常、stdout のバッファリングが原因です。通常、stdout が端末に送信されるときは、ライン バッファリングされます。改行が書き込まれるたびにフラッシュされます。しかし、stdout がパイプ (または、ファイルやソケットなどの端末ではないもの) の場合、完全にバッファリングされ、プログラムがフル バッファのデータ (たとえば 4 KB) を出力した場合にのみ書き込まれます。

多くのプログラムには、バッファリング動作を変更するためのコマンド ライン オプションがあります。たとえば、stdout が端末ではない場合でも、出力をラインバッファリングするように強制するフラグがありますgrep(1)--line-buffered外部プログラムにそのようなオプションがある場合は、おそらくそれを使用する必要があります。そうでない場合でも、バッファリングの動作を変更することは可能ですが、いくつかの卑劣なトリックを使用する必要があります。その方法については、この質問この質問を参照してください。

于 2013-03-20T05:43:39.243 に答える