5

所以我在这里有代码,我希望它严格运行 ls -l 5 次,但它似乎运行的次数要多得多。我在这里做错了什么?我想运行 ls 5 次,所以我 fork 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;
    }





}
4

3 回答 3

3

您正在循环中分叉,并且分叉准复制包括指令指针在内的过程。

含义:例如,您的第一个子进程将发现自己处于一个仍有 4 轮的循环中

并且处理产生的 4 个进程的每一个都会发现它必须再进行 3 轮。

等等。

fork()返回您所在的进程是父进程还是子进程。break;如果您在子进程中,您应该检查该返回值和循环。

" 成功时,父进程返回子进程的PID,子进程返回0。失败时,父进程返回-1,不创建子进程,并适当设置errno。"

所以你应该if(cpid==0) break;

于 2013-03-07T14:43:47.190 回答
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;
}
于 2013-03-07T15:13:52.183 回答
0

每个i'th在循环内fork开始,因此它将运行该循环的剩余迭代,递归地分叉。n-i

于 2013-03-07T14:43:49.630 回答