web-dev-qa-db-ja.com

Cでn個の子プロセスを正しくfork()する方法は?

それが私のコードです。

#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char *argv[] )
{
    int i, pid;

for(i = 0; i < atoi(argv[1]); i++) {
    pid = fork();
    if(pid < 0) {
        printf("Error");
        exit(1);
    } else if (pid == 0) {
        printf("Child (%d): %d\n", i + 1, getpid());
        exit(0); 
    } else  {
        wait(NULL);
    }
}

}

出力はそのようなものです。

Child (1): 5676
Child (2): 4624
Child (3): 4800
Child (4): 5596
Child (5): 5580

しかし、それは私の宿題で期待される出力ではありません。そうあるべきです。コードの何が問題になっていますか?誰かが私を助けることができますか?

Child (2): 4625
Child (1): 4624
Child (3): 4626
Child (4): 4627
Child (5): 4628

ご協力ありがとうございました。今から試してみます。

P.S.すみません、私の英語は下手です。私の言ったことをご理解いただければ幸いです。

12
Eric Tang

あなたのコードは私のコンピューターで完全に機能します。 OSに依存する可能性があります。

ただし、プログラムに引数が指定されていない場合のセグメンテーション違反を回避するために、argcが1に等しくないかどうかを確認する必要があります。

5
ClemPi

システムは、プロセスに割り当てるために無料のPIDを取ります。プロセスIDを4000にフォークし、子IDを3900にすることができます。最初のプロセスIDは決して同じではないため、宿題の紙に数字を入れてはいけません。

1
Eregrith

順序付けられていない出力が得られる理由は、どの子がいつアクティブになるかを正確に予測できないためです。そのため、2番目の子がfork()されて開始されるまで、最初の子の実行が遅れる場合があります。

これはOSに依存しますが、通常、子供はシーケンシャルPIDを取得します。

どちらの問題も、スケジュールされたタスクで問題になることはありません-絶対PIDは実際には重要ではありません(前述のように、すべてのOSは独自の処理を実行でき、PIDを順番にまたはランダムに割り当てます)。 :子の各部分の実行時間が異なる可能性があるため、出力が順序付けられません。これは、データが正しく転送されている限りカウントされます。これは、親がシーケンスを生成してからフォークする場合です。この場合、子プロセスのメモリレイアウトは、フォーク時の親プロセスのメモリレイアウトと同じです。したがって、親は、すでに実行中の子に影響を与えることなく、その「データ転送配列」を変更できます。

混乱を減らすために、すべての行のPIDの出力を削除することができます。子プロセスのそれぞれの開始時に出力できるかもしれませんが、その後は、たとえば次のように言うだけで十分です。 Child 3: straight length 6 <S6,H5,C4,S3,H2,SA>PIDを繰り返さずに。

1
glglgl

その期待される出力で、ほとんどの場合、宿題は最初にすべてのプロセスをフォークしてから、waitを呼び出す必要があります。

ループ内の待機呼び出しをスキップし、wait-1を返しerrnoECHILDに設定されるまでループする別の呼び出しを実行します。子の出力順序はランダムであるか、少なくとも完全な順序ではないため、必ずしも2 1 3 45である必要はないことに注意してください。

これは単なる推測ですが、より具体的な回答が必要な場合は、より多くの情報を提供する必要があります。

1
Per Johansson