これは与えられたコード例です:
# 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
ただし、プログラムを実行するたびに、プロセスの順序がランダムになります。私の質問は「なぜ?」です。プロセッサがプロセス間をジャンプする「コンテキストスイッチング」が原因ですか?一部のプロセスが他のプロセスよりも多く取得するのは「リソース割り当て」ですか?親と子のプロセスの順序が決まっていないので、ゾンビとオーファンのプロセスがありますか?
子プロセスは、fork()を実行するとすぐに実行を開始します。実際、子プロセスは「開始」すらしません。親プロセスと同様に、fork()の呼び出し後もコード内で続行します。 fork()の戻り値のみが異なります。親と子はどちらの順序でも終了できます。そうです、コンテキストの切り替えにより、すべてのプロセスがランダムに実行されます。
子プロセスが終了し、親が子終了コードを適切に「取得」しない場合、ゾンビプロセスが発生します。ゾンビプロセスは基本的に、まだ取得されていない終了コードのみで構成されており、終了コードが表示されるたびに、親プロセスが注意を払っていないことを非難します。 (ゾンビは親のバグです。ただし、親が短命であり、注意を払う必要がない場合を除きます。)親が子の前に終了すると、子プロセスはPID 1に再親化され、終了コードが実行されます。刈り取り。 (プロセスで発生したゾンビもクリーンアップします。)