我正在编写一个小程序,它在命令行中输入一个数字,并使用 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 语句确保进程在一个链中(每个父进程可以有一个子进程,并且继续向下),因为fork()
将子进程的 id 返回给父进程,将 0 返回给孩子。因此,分配的结果对于父级来说是非零/真,并强制它从循环中中断:
if(childpid = fork())
break;
在我添加wait(NULL)
调用之前,该函数打印了多行总和,不一定按顺序打印,我认为这应该是预期的,因为进程在不同的时间完成。有趣的是,如果我用大量数字(如 11221121)调用程序,它有时会打印一些总和,在它们中间输出我的 shell 提示符,并在挂在那里之前再打印一些,就像在无限中一样环形:
[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
(如您所见......),但这似乎在与子进程不同的“领域”中运行,并且在第一次打印后不会立即发生。