web-dev-qa-db-ja.com

「子」プロセスが親の前に終了するのはなぜですか?

これは与えられたコード例です:

# include <stdio.h>
# include <unistd.h>
void main() {
    static char *mesg[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
    int display(char *), i;
for (i=0; i<10; ++i)
    display(mesg[i]);
sleep(2);
}

int display(char *m) {
char err_msg[25];
switch (fork()) {
    case 0:
        execlp("/bin/echo", "echo", m, (char *) NULL);
        sprintf (err_msg, "%s Exec failure", m);
        perror(err_msg); return(1);
    case -1:
        perror ("Fork failure"); return(2);
    default:
        return(0);
}
}

さて、このプログラムを実行する前の私の仮定は、親が子の前に終了するということです。だから私の期待される出力は

0
1
2
3
4
5
6
7
8
9

ただし、プログラムを実行するたびに、プロセスの順序がランダムになります。私の質問は「なぜ?」です。プロセッサがプロセス間をジャンプする「コンテキストスイッチング」が原因ですか?一部のプロセスが他のプロセスよりも多く取得するのは「リソース割り当て」ですか?親と子のプロセスの順序が決まっていないので、ゾンビとオーファンのプロセスがありますか?

3
SopanhavuthSom

子プロセスは、fork()を実行するとすぐに実行を開始します。実際、子プロセスは「開始」すらしません。親プロセスと同様に、fork()の呼び出し後もコード内で続行します。 fork()の戻り値のみが異なります。親と子はどちらの順序でも終了できます。そうです、コンテキストの切り替えにより、すべてのプロセスがランダムに実行されます。

子プロセスが終了し、親が子終了コードを適切に「取得」しない場合、ゾンビプロセスが発生します。ゾンビプロセスは基本的に、まだ取得されていない終了コードのみで構成されており、終了コードが表示されるたびに、親プロセスが注意を払っていないことを非難します。 (ゾンビは親のバグです。ただし、親が短命であり、注意を払う必要がない場合を除きます。)親が子の前に終了すると、子プロセスはPID 1に再親化され、終了コードが実行されます。刈り取り。 (プロセスで発生したゾンビもクリーンアップします。)

2
Christoph Berg