所以我在这里有代码,我希望它能严格运行ls -l 5次,但似乎运行的次数要多得多。我在这做错了什么?我想跑ls 5次,所以我叉5次。也许我不理解等待的概念?我经历了大量的教程,似乎没有人能彻底解决使用fork的多个进程。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
pid_t pidChilds[5];
int i =0;
for(i = 0; i<5; i++)
{
pid_t cpid = fork();
if(cpid<0)
printf("\n FORKED FAILED");
if(cpid==0)
printf("FORK SUCCESSFUL");
pidChilds[i]=cpid;
}
}
答案 0 :(得分:3)
你在循环中分叉并且fork准复制包括指令指针在内的进程。
含义:例如,你的第一个子进程会发现自己处于一个循环中,仍有4轮可以去。
处理产生的4个进程中的每一个都会发现它必须再进行3轮。
等等。
fork()
返回您所在的流程是父流程还是子流程。如果您正在进行子进程,则应检查返回值和break;
循环。
“成功时,父进程返回子进程的PID,子进程返回0。失败时,父进程返回-1,没有创建子进程,并且正确设置了errno。 “
所以你应该if(cpid==0) break;
。
答案 1 :(得分:2)
当你在C中使用fork时,你必须想象将进程代码和状态复制到一个新进程中,此时它从它停止的地方开始执行。
在C中使用exec时,您必须想象如果调用成功,将替换整个过程。
这是您的代码,重写以产生预期的行为。请阅读评论。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
pid_t cpid;
pid_t pidChildren[5];
int i;
for (i = 0; i < 5; i++)
{
cpid = fork();
if (cpid < 0) {
printf("fork failed\n");
} else if (cpid == 0) {
/* If we arrive here, we are now in a copy of the
state and code of the parent process. */
printf("fork successful\n");
break;
} else {
/* We are still in the parent process. */
pidChildren[i] = cpid;
}
}
if (cpid == 0) {
/* We are in one of the children;
we don't know which one. */
char *cmd[] = {"ls", "-l", NULL};
/* If execvp is successful, this process will be
replaced by ls. */
if (execvp(cmd[0], cmd) < 0) {
printf("execvp failed\n");
return -1;
}
}
/* We expect that only the parent arrives here. */
int exitStatus = 0;
for (i = 0; i < 5; i++) {
waitpid(pidChildren[i], &exitStatus, 0);
printf("Child %d exited with status %d\n", i, exitStatus);
}
return 0;
}
答案 2 :(得分:0)
i
fork
每个n-i
都从循环开始,因此它将运行该循环的剩余{{1}}次迭代,递归分叉。