【发布时间】:2021-09-16 04:28:06
【问题描述】:
我正在尝试获取每个进程的退出状态以及它是否返回 1 或 0,并获取每个进程的总和(1 的数量和 0 的数量)。似乎最后一个返回 1 的进程是 while 循环中唯一正在等待的进程。
该程序将文件名作为命令行参数并确定它们是否存在。对于每个文件名(存在与否),一个新进程通过与父级的风扇关系派生,如果文件不存在,则返回错误状态。如果确实存在,则返回成功状态。然而,只有最后一个 PID 显示在 while 循环中。
int main(int argc, char *argv[]) {
pid_t pid;
int i, stat, suc = 0, fail = 0;
if (argc < 2){
printf("Usage: ./wordcount.exe [File_1] [File_2] [...] [File_n]\n");
exit(1);
}
for (i = 1; i < argc; i++){
if ((pid = fork()) == 0){
if (access(argv[i], F_OK) != 0){
fprintf(stderr, "Child process %ld for %s does not exist\n", (long)getpid(), argv[i]);
return 1;
}
fprintf(stderr, "Child process %ld for %s: Number of words is: %d\n", (long)getpid(), argv[i], 0);
exit(0);
}
}
while(1){
if (waitpid(pid, &stat, 0) == -1 && errno != EINTR) {
printf("pid var = %d\tstat=%d\n", pid, stat);
fail++;
break;
} else {
printf("pid var = %d\tstat=%d\n", pid, stat);
suc++;
}
}
printf("Parent process created %d processes to count %d words in %d files\n", (suc + fail), 0, (suc + fail));
printf("%d file(s) have been counted successfully!\n", suc);
printf("%d file(s) did not exist.\n", fail);
return 0;
}
Current output with 2 existing files and 2 non-existing:
$ ./wordcount.exe input_file_1.txt input_file_2.txt inputfail1 inputfail2
Child process 3565 for input_file_1.txt: Number of words is: 0
Child process 3566 for input_file_2.txt: Number of words is: 0
Child process 3567 for inputfail1 does not exist
Child process 3568 for inputfail2 does not exist
pid var = 3568 stat=256
pid var = 3568 stat=256
Parent process created 2 processes to count 0 words in 2 files
1 file(s) have been counted successfully!
1 file(s) did not exist.
【问题讨论】:
-
当然,在
for循环的每次迭代中,您都会覆盖变量pid,因此当它完成时,您只会看到最后一个值。如果你想跟踪所有的 pid,一个int变量是不够的;你需要一个数组。或使用waitpid(-1, &stat, 0)等待任何正在奔跑的孩子。 -
您的
if(waitpid(...) == -1)也不会测试孩子是否返回 0 或 1,它会测试孩子是否存在。所以你的一个“成功”是因为最后一个 pid 的孩子确实退出了(无论是退出代码 0 还是 1,你都没有检查),而你的一个“失败”是因为你试图等待同一个 pid再次,它不再存在,因为你已经在等待它。退出代码在stat变量中,您不会在计算suc和fail时使用其值。 -
要么将所有 PID 保存在一个数组中,以便您可以等待它们中的每一个。或者使用
wait()而不是waitpid()这样你就不需要指定PID。