1

私のプログラムは、子プロセスの数を3つに制限することになっています。

以下のコードを使用するとwaitpid、親プロセスが停止するため、最初のプロセスの後に子プロセスを作成できなくなります。使用しないwaitpid場合、アライブプロセスの数を減らすために子プロセスがいつ終了するかわかりません。

int numProcs = 0;
while(1==1) {
    /* 
     * inserts code that waits for incoming input 
     */
    numProcs++;
    pid = fork();
    if (pid == 0) {
        doStuff(); // may exit anytime, based on user input
    } else {
        if (numProcs > 3) {
            wait(&status);
            numProcs--;
        } else {
            waitpid(pid, &status, 0); // PROBLEM!
            numProcs--;
        }
    }
}

私は一日中この問題を探していました。誰かが助けることができますか?

4

2 に答える 2

3

明白になるリスクを冒して、基本的にはelse句を削除するだけです。探しているロジックは次のようなものです。

int max_active = 3; // or whatever
int number_active = 0;
bool done = false;

for (; !done; ++number_active) {
  // wait for something to do;
  GetSomeWork();
  // wait for something to finish, if necessary.
  for (; number_active >= max_active; --number_active)
    wait(&status);
  pid = fork();
  if (pid < 0)
    ReportErrorAndDie();
  if (pid == 0)
    DoTheWorkAndExit();
}

これにより、実際には、再起動せずにmax_activeの値を変更できます。これは、wait()呼び出しのforループの唯一の理由です。

明らかな不満は、私のバージョンのnumber_activeは、アクティブなプロセスの数を実際には教えてくれないということです。これは本当です。これは、待機していないプロセスの数を示します。つまり、ゾンビを保持する可能性があります(ただし、その数には制限があります)。常に最大数またはそれに近い数のタスクを実行している場合、これは問題ではありません。最大数が大きくない限り、設計要件はそれ以上使用しないことだけであるため、とにかく問題ではありません。タスクの最大数。したがって、アクティブな数が最大数を超えていないことを知っておく必要があります。

これが本当に気になり、タスクをクリーンアップしたい場合は、次のように入力できます。

for (; waitpid(-1, &status, WNOHANG) > 0; --number_active) {}

他のforループの前に、ブロックする必要があるかどうかを確認する前にゾンビを刈り取ります。(プロセスがまったくない場合にwaitpid(-1、&status WNOHANG)がエラーを返すかどうかは思い出せませんが、いずれにしても、エラーでループを続行しても意味がありません。)

于 2012-09-25T22:11:10.297 に答える
0

コードに2つの問題がありますが、2番目の問題は最初の問題によってマスクされています。

あなたの当面の問題は、waitpid(pid、&status、0);です。指定されたpidのプロセスが終了するまでブロックします。WNOHANGオプションを3番目のパラメーターとしてwaitpid()呼び出しに追加します。これにより、通話がブロックされないようになります。

これにより、新しい問題が追加されます。子プロセスが終了したかどうかを自分で確認する必要があります。これは、WIFEXITEDマクロを使用して実行できます。

} else {
  waitpid (-1, &status, WNOHANG);
  if (WIFEXITED(status)) {
    numProcs--;
  }
}

2番目の問題は、元のコードが最新のpidが作成されるのを待つだけであるということです。代わりに、すべての子プロセスである-1を待つ必要があります。

于 2012-09-25T22:11:30.407 に答える