我对C还很陌生,所以如果这是一个简单的问题,我很抱歉。我正在写一个C程序,部分内容如下。整个程序的目标是将文件从一个位置复制到另一个位置(文件作为参数传递,最终参数为目标)。下面的main()
使用fork()
为传递的每个文件创建一个子进程,我需要打印出文件名(只是输入参数)以及一条消息,该消息可能包括所有子进程运行后每个复制尝试的PID。
很明显,我可以获得并使用PID,这不是问题,但我如何才能获得与该进程相关的正确文件名/参数?我现在的方法显然是错误的;简单地按顺序遍历每个参数是不正确的。这将在Minix 2.0.4上运行,但我不知道这是否重要。
int
main(int argc, char *argv[])
{
int i, pid, rem, status;
int pids[argc];
char cfstatus[];
rem = argc;
for(i = 1; i < argc; i++) {
if((pids[i] = fork()) < 0) {
fprintf(stderr, "Error while forking");
}
else if(pids[i] == 0) {
if(copyfile(argv[i], argv[argc - 1]) == 1)
exit(4);
else
exit(0);
}
}
i = 0;
while(rem > 1) {
pid = wait(&status);
cfstatus = getcfstatus(status, pid);
printf("%-20s: %s", argv[i], cfstatus);
rem--;
i++;
}
}
如当前所写,PID存储在pids[i]
中的子进程将对argv[i]
命名的文件进行操作。这一点没有任何不确定性。i
通过fork
操作与其他所有内容一起被复制,并且此后不被修改。
但是,由于所有子项都是并行运行的,因此它们可以以任何顺序完成。也就是说,对wait
的每次调用都可能返回数组中的任何PID(尚未返回)。因此,在wait
循环中,您需要将从wait
返回的pid值映射回到pids
数组中的索引,然后您就知道了argv
中要打印的正确索引。对于这样的程序,通过数组进行线性搜索可能就足够了。
此行(除了"i"不能为0)存在一些问题
"if(copyfile(argv[i], argv[argc - 1]) == 1)'
如果命令行为:程序名srcFile desFile
则argc=3那么argv[argc-1]=srcFile,这不是想要的
建议:
'if(copyfile(argv[i], argv[argc]) == 1)'
然后,为了避免写入输出/desFile 时出现竞争条件
一次只能有一个进程写入该文件。
因此,将多个进程分叉到同一个文件是一个错误
此行:
'for(i = 0; i < argc; i++) {'
需要对避免尝试将可执行文件复制到desFile并避免试图将desFile复制到自身
建议:
'for(i = 1; i < (argc-1); i++) {'