1

探してもだめだったので、やっと助​​けを求めるようになりました。私の課題には、(RedHat Linux で実行される C で) 2 つの子プロセスを作成することが含まれます。それぞれの子プロセスは、パイプに任意の反復回数の文字を書き込みます。このパイプは、それらを作成した親プロセスと共有されます。親はパイプから読み取りますが、子はパイプに書き込む文字をまだ持っています。子が終了し、パイプが空になると、親 (メイン) を終了できます。

これは、私が書いたコードのロジックの簡単で汚い例です。

main()
{
      //create pipe

      fork(); //childA
      //writes to pipe 

      fork(); //childB
      //writes to pipe

      //parent reading
      while(condition) {
          //read from pipe + print chars to terminal
      }
}

さて、私の質問は、while ループの条件に関するものです。パイプがいっぱいになったために子供たちが書き込みをブロックされているときに読み取る必要がありますが、どのような条件でこれを行うことができるのかわかりません。どんな助けでも絶対に素晴らしいでしょう。

4

1 に答える 1

0

読むときにパイプがいっぱいである必要があるというのは要件ですか? それとも、パイプの 1 つがいっぱいで、子の書き込みがブロックされている場合でも、両方の子から読み取り続ける必要があるだけですか?

パイプがいっぱいになった場合に高くする標準的な方法はわかりません。FIONREADioctl を使用して、パイプで読み取るデータの量を判断しPIPE_BUF、それPIPE_BUFをそれ以上PIPE_BUF; その呼び出しは、パイプをいっぱいにすることなくブロックする可能性があります。私はこのテクニックが機能することに頼りません。

2 つのファイル記述子から読み取りを続ける通常の方法は、どちらが準備できているかに関係なく、selectシステム コールを使用することです。これにより、いずれかのファイル記述子でデータが利用可能になるまで待つことができます。これは、親プロセスが、使用可能なデータを持たない 1 つの子からの読み取りをブロックしないことを意味しますが、もう 1 つの子はバッファーがいっぱいであるためにブロックされています。

編集:質問を読み直した後、実際には両方の子供が書き込んでいるパイプが1つしかないように思えます。あれは正しいですか?繰り返しますが、子供たちがブロックするまで待つ必要があるかどうかという質問が出てきます. 親が単にパイプから読み取る場合、子の 1 つがパイプに書き込むまでブロックされます。特別なことをする必要はありません。

パイプが実際にいっぱいになるまで待つ必要がある場合は、正確な文言を確認したいと思います.

編集 2 : コメントでの質問への回答:

  1. 親プロセスのコードは、プログラム内の 2 つの子プロセスのコードに従う必要がありますか?

    いいえ、親プロセスまたは子プロセスのコードの順序に関する要件はありません。親が実行するコードと子が実行するコードを区別するために、 の戻り値をチェックしますfork()。戻り値が 0 の場合、子プロセスにいます。そうでない場合は、親にいます。戻り値が -1 の場合はエラー、正の場合は子プロセスの PID です。

    したがって、次のようなコードを記述できます。

    int pid = fork();
    if (pid) { 
        // in the parent, check if pid is -1 for errors
    } else {
        // in the child
    }
    

    または:

    int pid = fork();
    if (pid == 0) {
        // in the child, do whatever you need to do and...
        exit(0);
    }
    
    // in the parent; since the child calls exit() above, control will never
    // reach here in the child.  Or you could do an execl() in the child, which 
    // replaces the current program with another one, so again, control will 
    // never reach here within the child process.
    
  2. 2 つの子が終了し、パイプが空になるまでパイプから読み取り続けるにはどうすればよいですか?

    パイプの読み取り側では、すべてのプロセスがパイプの書き込み側を閉じ、すべてのデータがパイプから読み取られるまで、0 を返しませんreadread何かがまだ開いているが、パイプにデータがない場合、データがパイプにread書き込まれるまでブロックされます。

    落とし穴の 1 つは、試行する前に、親プロセスでパイプの書き込み側を閉じることを忘れないことreadです。そうしないと、子が終了した後に親が a を実行しようとすると、親readが独自のパイプを閉じるのを待ってブロックされます。

于 2012-11-07T23:35:58.897 に答える