コマンドラインで数値を受け取り、 fork() を使用して数値の桁を合計する一連のプロセスを作成する小さなプログラムを作成しています。これまでのところ、次のとおりです。
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char* argv[]){
if(argc != 2){
printf("Usage: sod [number] \n"); /* -o sod when compiled */
exit(1);
}
pid_t childpid = 0;
int sum = 0;
int i;
for(i = 0; i < strlen(argv[1]); i++){
/* atoi needs a string */
char str[2];
str[0] = argv[1][i]; str[1] = 0;
sum += atoi(str);
if(childpid = fork())
break;
}
wait(NULL);
printf("sum: %d\n", sum);
exit(0); /* probably redundant... */
return 0;
}
私のシステムブックで理解できることから、if ステートメントは、プロセスがチェーン内にあることを保証します (各親は 1 つの子を持つことができ、それは下に続きます)。これfork()
は、子の ID を親プロセスに返し、0 を子。したがって、代入の結果は親に対して非ゼロ/真であり、強制的にループから抜け出します。
if(childpid = fork())
break;
呼び出しを追加する前にwait(NULL)
、関数は合計の複数行を出力しましたが、必ずしも順序どおりではありませんでした。これは、プロセスが異なる時間に終了するため、予想されるはずです。興味深いことに、11221121 のような桁数の多いプログラムを呼び出すと、合計の一部が出力され、その中間にシェル プロンプトが出力され、さらにいくつか出力されてから、まるで無限にあるかのようにそこにぶら下がります。ループ:
[nvj]@sun ~/313/sod> (12:15:21 02/10/13)
:: sod 11221121
sum: 1
sum: 2
sum: 4
sum: 6
sum: 7
sum: 8
sum: 10
[nvj]@sun ~/313/sod> (12:15:24 02/10/13)
:: sum: 11
sum: 11
[hangs here...]
なぜこれが起こっているのかについての私の唯一の推測は、何かがタイムアウトしているか、他の人を待つ必要があるものが轍になっているということです. プログラムを実際に終了させる (そして何らかの順序で合計を出力する) ために、wait(NULL)
呼び出しを追加しました。私が理解していることから、続行する前に親がすべての子を待つ必要があります。当然のことながら、これにより、最後に作成された子が終了すると、実際の合計が最初に出力され、残りが順番に続きます。
[
nvj]@sun ~/313/sod> (12:25:02 02/10/13)
:: sod 12389492182398
sum: 69
sum: 69
sum: 61
sum: 52
sum: 49
sum: 47
sum: 39
sum: 38
sum: 36
sum: 27
sum: 23
sum: 14
sum: 6
sum: 3
sum: 1
ありがたいことに、この場合、プログラムは実際に終了します。しかし、実際の合計を持つ子が戻ってその結果を表示したときに、それを正しく終了させる方法はありますか? フラットアウト呼び出しなどを試してみましたがexit
(ご覧のとおり...)、これは子プロセスとは異なる「領域」で動作しているようで、最初の印刷の直後には発生しません。